众所周知,我们可以像这样使用foldr
找到列表的 head :
head'' :: [a] -> a
head'' = foldr (\x _ -> x) undefined
但是,是否可以使用 foldl
来获得相同的结果?
类似地,我们可以使用foldl
找到list的 last 元素,如下所示:
last'' :: [a] -> a
last'' = foldl (\_ x -> x) undefined
是否可以使用 foldr
来获得相同的结果?
答案 0 :(得分:3)
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
,它是相同的,但是翻转了。
答案 1 :(得分:1)
首先想到的是使用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
last
当然也是如此,使用foldr1