使用foldl和使用foldr的最后一个元素查找列表的头



众所周知,我们可以使用 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也是如此

最新更新