Haskell - 在 Monad 中提取 Maybe

Haskell - Extract Maybe in Monad

我正在研究 Project Euler 的问题 9,我有一个关于在另一个 monad 中提取 maybe 值的最佳方法的问题。题目要求找到'a'、'b'、'c'满足:

我写了下面的代码解决了这个问题:

problem9 :: (Integral a) => a -> [(a, a, a)]
problem9 n =
    do
        a <- [1..n]
        b <- [1..a]
        c <- fromJustM (findC a b)
        guard (a + b + c == n)
        return (a, b, c)

'c' 可以通过分析计算,但是,由于它可能不存在,我 return 可能是一个值。

findC :: (Integral a) => a -> a -> Maybe a
findC a b = ... (implementation) ...

为了提取列表 monad 中的 maybe 值,我创建了以下函数:

fromJustM :: (Monad m) => Maybe a -> m a
fromJustM (Just a) = return a
fromJustM Nothing = fail ""

看起来这应该是一个常见的操作,那么是否有标准库函数可以执行此操作,或者是否有更惯用的方法来执行此操作?

fail 实际上不是单子操作;由于历史事故/隐藏一些肮脏的错误处理,它仅在 Monad 类型 class 中。

更合适的 class 是 MonadPlus, or rather its Applicative correspondent Alternative. fail translates to empty。这样,您的签名实际上应该是

fromJustM' :: Alternative m => Maybe a -> m a

Hoogle offers

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

符合要求:MaybeFoldable

        c <- asum $ pure <$> findC a b

可以说,这实际上不是那么可读。


您实际上可以通过写作

更轻松地实现您的目标
        Just c <- pure $ findC a b

这再次使用了 fail 方法:pattern-match 失败在 do 块中隐式调用它。