我想创建一个"地图查找"功能使用折叠。
这是我的地图" (只是一个元组列表):
phoneBook:: [([Char], [Char])]
phoneBook = [("bob", "00-21-55")
,("jack", "55-51-55")
,("joe", "10-61-25")
,("susy", "06-21-55")
,("clara", "50-31-95")
]
这就是我想写的功能:
lookUp :: (Eq k) => k -> [(k,v)] -> v
lookUp k = foldl1 (\acc (x,y) -> if k == y then y else acc)
然而,这不编译,它产生一个"不能构造无限类型"错误。
你能解释一下为什么这是错误的以及如何让它发挥作用?
请注意,我知道Data.Map及其导出的地图功能,我想这样做只是为了了解折叠是如何工作的。
答案 0 :(得分:5)
首先是工作版本 - 我会在几分钟后回来解释:
ASP.net MVC
你遇到的问题是:
lookUp :: (Eq k) => k -> [(k,v)] -> Maybe v
lookUp k = foldl (\ acc (k',v) -> if k == k' then Just v else acc) Nothing
,您的类型为foldl1
,因此您的元素和结果需要相同的类型 - 但是在这里您希望将值作为结果,但折叠键/值对的元组。 foldl1 :: (a -> a -> a) -> [a] -> a
(请注意,如果这是正确的选择,我不感兴趣 - 请参阅foldl
vs foldl'
vs {{1} })foldl
- 当然这个这样可以很容易地找到初始值:foldr
如果你不喜欢Maybe v
部分,你可以使用Nothing
而不是这样:
Maybe
这不是最有效的实现,因为无论你是否找到了密钥,你都会仔细查看所有列表 - 随意尝试提出一些可以做到的事情
提示:Haskell是懒惰的 - 也许你可以通过过滤掉正确的键/值对来找到一些东西,拿出这个的安全头然后maping到值部分;))