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

标签 haskell

我有功能:

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/

相关文章:

haskell - 无限生成汉明序列的最新技术

haskell - Netwire 5 中的 Kleisli Arrow?

haskell - 为什么 GHC 无法确定在此 case 语句中使用哪个字段?

haskell - 787有什么特别之处?

haskell - 在 Haskell 中懒惰地评估一元函数

parsing - Haskell:读取一个数字(整数或 float )

haskell - 使用 FlexibleContexts 和 FlexibleInstances 有哪些陷阱?

haskell - 如何在haskell中处理通用反序列化?

haskell - 在 Haskell 中共享力的计算

Haskell:在惰性 IO 中隐藏故障