首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用类foldl递归的Haskell

使用类foldl递归的Haskell
EN

Stack Overflow用户
提问于 2014-01-22 22:34:02
回答 2查看 429关注 0票数 4

我正在尝试让一个函数工作,它使用foldl来遍历一个元组列表,并从中创建一个字符串。我正在尝试创建一个已经使用递归工作的类似函数。

下面是我正在试图编译的代码:

代码语言:javascript
复制
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参数类型与预期的不匹配,但对我来说一切似乎都还好。

代码语言:javascript
复制
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

我感谢所有的反馈。谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-22 22:46:49

您为foldl提供了具有String -> String -> String类型的(++)函数。但是,您正在折叠的集合xs具有[(String, String, Integer)]类型,而不是[String]类型。

您可以将bibliography_fold更改为

代码语言:javascript
复制
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold [] = ""
bibliography_fold (x:xs) = foldl (++) (citeBook x) (map citeBook xs)

或者只是为了

代码语言:javascript
复制
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold xs = foldl (++) "" (map citeBook xs)

但我是Haskell的一个相对菜鸟,所以我的编码风格有点含混不清。

另外,您需要编写(citeBook x)而不是citeBook(x),否则编译器会假设citeBook(x)都是foldl的参数(如果我错了,请纠正我)。这有助于解释为什么您收到的错误消息看起来如此奇怪。

票数 4
EN

Stack Overflow用户

发布于 2014-01-22 23:08:46

您已经得到了答案,所以我将提供另一种使用折叠来解决这个问题的方法:

代码语言:javascript
复制
bibliography_fold :: [(String, String, Integer)] -> String
bibliography_fold = foldr ((++) . citeBook) ""

没有地图,没有特例,而且它可以用点自由的方式书写。我鼓励您在GHCi中解构这个表达式,并使用:info检查每个组件,以探索它的实际工作方式。看看foldr++citeBook(++) . citeBook的类型,看看能不能找出为什么会起作用。您可能也希望查找foldr的源代码。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21295451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档