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

时间:2019-05-02 13:23:46

标签: haskell fold

众所周知,我们可以像这样使用foldr找到列表的 head

head'' :: [a] -> a
head'' = foldr (\x _ -> x) undefined

但是,是否可以使用 foldl 来获得相同的结果?

类似地,我们可以使用foldl找到list的 last 元素,如下所示:

last'' :: [a] -> a
last'' = foldl (\_ x -> x) undefined

是否可以使用 foldr 来获得相同的结果?

2 个答案:

答案 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