众所周知,我们可以使用 foldr
的列表找到 head :
head'' :: [a] -> a
head'' = foldr (x _ -> x) undefined
但是,有什么方法可以使用 foldl
?
同样,我们可以使用foldl
这样的列表的最后一个元素:
last'' :: [a] -> a
last'' = foldl (_ x -> x) undefined
有什么方法可以使用 foldr
?
head
不能用 foldl
编写,因为 foldl
进入了无限列表上的无限循环,而 head
却没有。否则,当然:
head' :: [a] -> a
head' = fromJust . foldl (y x -> y <|> Just x) Nothing
丢弃安全版本的fromJust
。
last
绝对可以以foldr
的形式写,以相同的方式:
last' :: [a] -> a
last' = fromJust . foldr (x y -> y <|> Just x) Nothing
对于head
,我们从Nothing
开始。第一个元素(想要的一个(包裹在Just
中,并用(<|>)
"覆盖" Nothing
。以下元素被忽略。对于last
,大约相同,但翻转。
想到的第一件事是使用foldl1
而不是foldl
,然后:
head'' :: [a] -> a
head'' = foldl1 (x _ -> x)
,并且由于foldl1
是根据 foldl
定义的,如果列表是非空的(并且如果列表为空,则崩溃 - 但是head
也是如此(:
foldl1 f (x:xs) = foldl f x xs
我们可以说
head'' (x:xs) = foldl (x _ -> x) x xs
当然,使用foldr1
last
也是如此