这里是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.
答案 0 :(得分:4)
foldr
和foldl
的类型略有不同:
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