gpt4 book ai didi

haskell - 如何声明两种类型的组合是一个 monad

转载 作者:行者123 更新时间:2023-12-02 10:26:51 26 4
gpt4 key购买 nike

我有功能:

step :: forall m . (MonadState IntCodeState m) => m (Maybe ())

当我使用do时函数体中的符号,它使用 m作为单子(monad)。正如您所料,我实际上希望它使用 m Maybe 。但是,它不明白 m Maybe是一个单子(monad)。我如何向 Haskell 表达这一点?

编辑:目前这可能有点畸形。具体类型应该是 StateT IntCodeState Maybe () ,但我试图不声明具体类型,所以问题是:如何声明?

编辑2:另一种尝试:我有一些如下所示的函数:

getValueIndex :: (MonadState IntCodeState m) => Int -> m (Maybe Int)

在这里,我正在研究状态单子(monad)的级别。然而,我现在希望能够表现得“好像”m Maybe是单子(monad)。我希望这很简单,但我不知道如何表达它。我想要编写的代码如下所示

step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
step = do
full <- opCode
let len = length (snd full) + 1
process full <* (next += len)

但是 opCode 返回 m (Maybe a)我想要 full成为a

最佳答案

But opCode returns a m (Maybe a) and I want full to be an a

看起来您想使用 MaybeT monad transformer ,其底层是 m (Maybe a),它的 Monad 实例可以满足您的需要:

The MaybeT monad transformer extends a monad with the ability to exit the computation without returning a value.

A sequence of actions produces a value only if all the actions in the sequence do. If one exits, the rest of the sequence is skipped and the composite action exits.

以下是类型:

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

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

这也会很有帮助,专门来自 MonadTrans:

lift :: m a -> MaybeT m a 

所以在你的情况下:

step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
step = runMaybeT $ do
full <- MaybeT opCode -- :: MaybeT opCode :: MaybeT m a, full :: a
let len = length (snd full) + 1
lift $ process full <* (next += len)

我假设 process 返回一个 m () 并使用 lift 将其更改为 MaybeT m ().

关于haskell - 如何声明两种类型的组合是一个 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59494015/

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