gpt4 book ai didi

Haskell - 在 Monad 中提取 Maybe

转载 作者:行者123 更新时间:2023-12-01 18:43:20 24 4
gpt4 key购买 nike

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

  • a^2 + b^2 = c^2
  • a + b + c = 1000

我编写了以下代码来解决该问题:

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' 可以通过分析计算,但是,由于它可能不存在,我返回一个可能的值。

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

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

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

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

最佳答案

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

更合适的类是 MonadPlus ,或者更确切地说是它的 Applicative 对应项 Alternative失败 翻译为 empty 。这样,您的签名实际上应该是

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

发送给 Hoogle offers

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

这符合要求:也许是一个可折叠

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

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

<小时/>

实际上,通过写作,您可以更轻松地实现目标

        Just c <- pure $ findC a b

这再次使用了 fail 方法:do block 中的模式匹配失败隐式调用它。

关于Haskell - 在 Monad 中提取 Maybe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34983308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com