gpt4 book ai didi

haskell - 涉及包含 Maybe 的容器的一些 monad 包装/解包/绑定(bind)困惑

转载 作者:行者123 更新时间:2023-12-02 04:55:42 24 4
gpt4 key购买 nike

这里有一些示例代码

foo :: a -> Identity (Maybe a)
foo a = do
maybeStuff <- getStuffSometimes a
return $ case maybeStuff of -- this "case" stuff is the kind
Just stuff -> Just $ getStuffAlways stuff -- of code I'd expect the Maybe
Nothing -> Nothing -- monad to help with

getStuffSometimes :: a -> Identity (Maybe a)
getStuffSometimes a = return $ Just a

getStuffAlways :: a -> Identity a
getStuffAlways = return

-- ERROR (on the return statement of the do block)
-- Expected type: Identity (Maybe a)
-- Actual type: Identity (Maybe (Identity a))

可能有点不清楚我要做什么,所以这里有更详细的描述:

  • 为了演示,所有有趣的东西都包装在计算上下文/容器中——在本例中为 Identity。在我的实际代码中,我当然还有另一个 monad。

  • foogetStuffSometimes 应该接收 a 类型的东西并返回一个 Maybe a 包裹在上下文中——也就是说,它们要么返回 Identity (Just a)(计算成功),要么返回 Identity Nothing(计算失败)。

  • getStuffAlways 是一个永不失败的计算 -- 它总是返回 Identity a

  • 我希望foo:

    1. 运行一个失败的计算
    2. 如果可失败计算失败,则失败(无)
    3. 如果失败计算成功,将其与 getStuffAlways 绑定(bind),并返回只是(getStuffAlways 的结果到#1 的结果)

这是 Monad Transformers 的用例情况吗?在我的例子中,我实际的 monad 有点复杂,是我的库在 IO 之上给出的多个转换器的堆栈,我不完全确定如何让它在这种情况下工作(我会在另一个问题中问它结果是我必须使用变压器)


跟进:

在现实生活中我有更像:

foo :: a -> Identity (a, Maybe a)
foo a = do
firstPart <- getStuffAlways a

maybeStuff <- getStuffSometimes a
secondPart <- case maybeStuff of
Just stuff -> Just $ getStuffAlways stuff
Nothing -> Nothing

return (firstPart, secondPart)

在这种情况下,构建堆栈的最佳方法是什么?

最佳答案

是的,这是 monad 转换器的用例。给定类型的计算:

computation :: (Monad m) => m (Maybe a)

...您可以使用同名的 MaybeT 构造函数将其包装在 MaybeT 中:

MaybeT :: (Monad m) => m (Maybe a) -> MaybeT m a

MaybeT computation :: (Monad m) => MaybeT m a

然后你就可以写:

foo :: MaybeT Identity a
foo = do
stuff <- MaybeT getStuffSometimes
lift $ getStuffAlways stuff

... 和 MaybeT 将为您处理所有的 Nothing 检查,确保将它们穿入您的其他 monad。

当你完成后,只需使用 runMaybeT 来解包结果,在返回 Maybe 的基础 monad 中返回一个 Action :

runMaybeT :: (Monad m) => MaybeT m a -> m (Maybe a)

例如:

runMaybeT foo :: Identity (Maybe a)

编辑:要回答您的后续问题,您只需:

foo a = do
firstPart <- getStuffAlways
secondPart <- runMaybeT $ do
stuff <- MaybeT getStuffSometimes a
lift $ getStuffAlways stuff
return (firstPart, secondPart)

关于haskell - 涉及包含 Maybe 的容器的一些 monad 包装/解包/绑定(bind)困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18026492/

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