【发布时间】:2019-04-27 18:47:25
【问题描述】:
在著名的Haskell tutorial 中,首先定义了在关联列表中逐键查找值的函数:
findKey :: (Eq k) => k -> [(k,v)] -> Maybe v
findKey key [] = Nothing
findKey key ((k,v):xs) = if key == k
then Just v
else findKey key xs
然而,作者随后认为这种类型的“教科书递归”应该更好地使用折叠来实现:
findKey key = foldr (\(k,v) acc -> if key == k then Just v else acc) Nothing
我觉得这很令人困惑。我说的对吗:
- 基于
foldr的函数总是会在产生结果之前遍历整个列表,而第一个会在发现后立即停止? - 因此,第一个函数将在无限列表上运行,而第二个函数则不行?
在我看来,真的 等效定义将使用scanr 代替,并从中获取不是Nothing 的第一个结果。 (?)
【问题讨论】:
-
尝试在无限列表上使用基于 foldr 的版本。您是否必须等待无限时间才能得到结果?如果不是,则此版本不会遍历整个列表。