我正在尝试使用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
我感谢任何反馈。谢谢!
答案 0 :(得分:4)
您向foldl
(++)
函数提供了类型为String -> String -> String
的函数。但是,您折叠的收藏集xs
的类型为[(String, String, Integer)]
,而不是[String]
类型。
您可以将bibliography_fold
更改为
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold [] = ""
bibliography_fold (x:xs) = foldl (++) (citeBook x) (map citeBook xs)
或只是
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold xs = foldl (++) "" (map citeBook xs)
但我自己是Haskell的亲戚,所以请把我的编码风格带上一粒盐。
此外,您需要编写(citeBook x)
而不是citeBook(x)
,否则编译器会认为citeBook
和(x)
都是foldl
的参数(正确)我,如果我错了)。这有助于解释为什么你得到的错误信息看起来很奇怪。
答案 1 :(得分:3)
您已经得到了答案,因此我将提供另一种使用折叠来解决此问题的方法:
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold = foldr ((++) . citeBook) ""
没有地图,没有特殊情况,它可以用自由点风格书写。我鼓励你在GHCi中解构这个表达式,并使用:info
检查每个组件以探索它是如何工作的。查看foldr
,++
,citeBook
,(++) . citeBook
的类型,看看您是否可以找出其工作原理。您可能还想查找foldr
的源代码。