【发布时间】:2014-02-13 06:00:08
【问题描述】:
我正在尝试让一个使用 foldl 的函数工作 遍历元组列表并从中创建一个字符串。 我正在尝试创建一个已经使用递归的类似函数。
这是我要编译的代码:
citeBook :: (String, String, Integer) -> String
citeBook (name, titl, date) = (titl ++ " (" ++ name ++ ", " ++ show date ++ ")\n")
--Recursion function
-- function must be called with putStr in order for newlines to work
bibliography_rec :: [(String, String, Integer)] -> String
bibliography_rec [] = ""
bibliography_rec xs = (citeBook(head xs) ++ bibliography_rec (tail xs))
--foldl function
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold [] = ""
bibliography_fold (x:xs) = foldl (++) citeBook(x) xs --ERROR HERE
所以在提供的代码的最后一行,我试图让 foldl 使用 (++) 作为运算符以组合列表中的字符串。 我使用 citeBook(x) 作为我的基本情况,因为 x 将是第一个元组 从列表中取出。注意 citeBook(x) 返回一个字符串。然后继续 与列表 xs 折叠。
这是我遇到的错误。我认为我的 foldl 参数类型不是 符合预期,但对我来说一切似乎都很好..
hw1.hs:28:34:
Couldn't match type `[a0]'
with `(String, String, Integer) -> String'
Expected type: ((String, String, Integer) -> String)
-> [a0] -> (String, String, Integer) -> String
Actual type: [a0] -> [a0] -> [a0]
In the first argument of `foldl', namely `(++)'
In the expression: foldl (++) citeBook (x) xs
In an equation for `bibliography_fold':
bibliography_fold (x : xs) = foldl (++) citeBook (x) xs
hw1.hs:28:48:
Couldn't match expected type `[[a0]]'
with actual type `(String, String, Integer)'
In the third argument of `foldl', namely `(x)'
In the expression: foldl (++) citeBook (x) xs
In an equation for `bibliography_fold':
bibliography_fold (x : xs) = foldl (++) citeBook (x) xs
hw1.hs:28:51:
Couldn't match expected type `(String, String, Integer)'
with actual type `[(String, String, Integer)]'
In the fourth argument of `foldl', namely `xs'
In the expression: foldl (++) citeBook (x) xs
In an equation for `bibliography_fold':
bibliography_fold (x : xs) = foldl (++) citeBook (x) xs
感谢任何和所有反馈。谢谢!
【问题讨论】:
-
bibliography_rec不只是concatMap citeBook? -
是的,将其发布为答案。
-
bheklilr,我刚刚尝试过,它确实有效,但我明确地试图创建一个递归函数。我的问题是我试图像 bibliography_rec 一样打印出一个列表,但是使用 foldl 而不是递归
-
一些小注意事项:首先, bibliography_rec 将串联关联到右侧,因此您应该使用 foldr insread 的 foldl 来获得等效函数(结果是相同的,因为 ++ 是关联的,但是右关联版本的效率更高)。此外,最好在 bibliography_head 上使用模式匹配而不是 head 和 tail。
标签: haskell recursion types fold