从 [Maybe a] 中提取第一个 Just 值

11

假设我有一个列表:

[Nothing, Just 1, Nothing, Just 2]

我想要获取第一个Just(非错误)的值;在这个例子中,它是Just 1。我能想到的唯一办法是:

我想要获取第一个Just(非错误)的值;在这个例子中,它是Just 1。我能想到的唯一办法是:

firstJust xs = case filter isJust xs of
                 []     -> Nothing
                 Just x -> Just x

是否有更好/单子泛型的方法来做这件事?

2个回答

26

msum 函数来自于 Control.Monad 模块:

\> msum [Nothing, Just 1, Nothing, Just 2]
Just 1

或者使用来自Data.Foldableasum函数:

\> asum [Nothing, Just 1, Nothing, Just 2]
Just 1

两者都被记录为:

一组操作的总和,概括了concat

签名如下:

msum :: (Foldable t, MonadPlus m) => t (m a) -> m a
asum :: (Foldable t, Alternative f) => t (f a) -> f a

由于 Maybe 实现了 Alternative 接口,因此它行为与上述相同。


4
Maybe替换为First后,你可以直接使用fold函数。 - dfeuer
似乎需要firstJust xs = asum xs <|> Nothing来处理空列表。 - Steven Shaw
1
@StevenShaw asum ([] :: [Maybe Int])Nothing,所以空列表没有问题。 - Neil Mayhew
@dfeuer 这样做的好处是您可以使用相同的方法来使用 Last - Neil Mayhew

4
import Data.Foldable (find)
import Data.Maybe (isJust)
import Control.Monad (join)

firstJust = join . find isJust

使用方法:

> firstJust [Nothing, Just 1, Nothing, Just 2]
Just 1

> firstJust [Nothing, Nothing]
Nothing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接