为什么这种情况的语法不能正确编译?

时间:2019-10-01 04:34:59

标签: haskell

这里是Haskell的新手。我不确定为什么这种语法情况无法正确编译:

-- | Use column headers to determine offsets for each row in a table
splitHeader :: Alignment -> String -> [(String,Int)]
splitHeader a h = case a of
            AlignLeft -> reverse ((foldr f b h) ("", 0) [] 2)
            AlignRight -> reverse ((foldl f b h) ("", 0) [] 2) 
    where b (n', w') l' m' = (reverse n', w'):l'
          f c b (n, w) l m 
              | m == 2 && c == ' ' = b (n, w+1)   l 0
              | m == 2 && c /= ' ' = b (c:n, w+1) l 1
              | m == 1 && c == ' ' = b (n, w+1)   l 0
              | m == 1 && c /= ' ' = b (c:n, w+1) l 1
              | m == 0 && c == ' ' = b (n, w+1)   l 0
              | m == 0 && c /= ' ' = b ([c], 1)   ((reverse n, w):l) 1

编译错误:

Kata.hs:50:43: warning: [-Wdeferred-type-errors]
    • Couldn't match type ‘([Char], Int)
                           -> [([Char], Int)] -> Integer -> [([Char], Int)]’
                     with ‘Char’
      Expected type: (([Char], Int)
                      -> [([Char], Int)] -> Integer -> [([Char], Int)])
                     -> (([Char], Int) -> [([Char], Int)] -> Integer -> [([Char], Int)])
                     -> ([Char], Int)
                     -> [([Char], Int)]
                     -> Integer
                     -> [([Char], Int)]
        Actual type: Char
                     -> (([Char], Int) -> [([Char], Int)] -> Integer -> [([Char], Int)])
                     -> ([Char], Int)
                     -> [([Char], Int)]
                     -> Integer
                     -> [([Char], Int)]
    • In the first argument of ‘foldl’, namely ‘f’
      In the first argument of ‘reverse’, namely
        ‘((foldl f b h) ("", 0) [] 2)’
      In the expression: reverse ((foldl f b h) ("", 0) [] 2)
   |
50 |             AlignRight -> reverse ((foldl f b h) ("", 0) [] 2)
   |                                           ^

Kata.hs:50:47: warning: [-Wdeferred-type-errors]
    • Couldn't match type ‘Char’
                     with ‘([Char], Int)
                           -> [([Char], Int)] -> Integer -> [([Char], Int)]’
      Expected type: [([Char], Int)
                      -> [([Char], Int)] -> Integer -> [([Char], Int)]]
        Actual type: String
    • In the third argument of ‘foldl’, namely ‘h’
      In the first argument of ‘reverse’, namely
        ‘((foldl f b h) ("", 0) [] 2)’
      In the expression: reverse ((foldl f b h) ("", 0) [] 2)
   |
50 |             AlignRight -> reverse ((foldl f b h) ("", 0) [] 2)
   |                                               ^
Ok, one module loaded.

1 个答案:

答案 0 :(得分:4)

foldrfoldl的类型略有不同:

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

但是您要向两个传递相同的功能f

如果您将参数f替换为flip f,则可以得出以下类型:

splitHeader :: Alignment -> String -> [(String,Int)]
splitHeader a h = case a of
            AlignLeft ->  reverse ((foldr f b h) ("", 0) [] 2)
            AlignRight -> reverse ((foldl (flip f) b h) ("", 0) [] 2) 
    where b (n', w') l' m' = (reverse n', w'):l'
          f c b (n, w) l m 
              | m == 2 && c == ' ' = b (n, w+1)   l 0
              | m == 2 && c /= ' ' = b (c:n, w+1) l 1
              | m == 1 && c == ' ' = b (n, w+1)   l 0
              | m == 1 && c /= ' ' = b (c:n, w+1) l 1
              | m == 0 && c == ' ' = b (n, w+1)   l 0
              | m == 0 && c /= ' ' = b ([c], 1)   ((reverse n, w):l) 1