我正在尝试让一个函数工作,它使用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我感谢所有的反馈。谢谢!
发布于 2014-01-22 22:46:49
您为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的参数(如果我错了,请纠正我)。这有助于解释为什么您收到的错误消息看起来如此奇怪。
发布于 2014-01-22 23:08:46
您已经得到了答案,所以我将提供另一种使用折叠来解决这个问题的方法:
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold = foldr ((++) . citeBook) ""没有地图,没有特例,而且它可以用点自由的方式书写。我鼓励您在GHCi中解构这个表达式,并使用:info检查每个组件,以探索它的实际工作方式。看看foldr、++、citeBook、(++) . citeBook的类型,看看能不能找出为什么会起作用。您可能也希望查找foldr的源代码。
https://stackoverflow.com/questions/21295451
复制相似问题