适用的< *>在ReaderT StateT IO中

时间:2016-06-05 10:45:51

标签: haskell monad-transformers

在ReaderT StateT IO do block中我试图使用<*>使用Maybe参数调用Maybe中的函数,但这会导致类型错误。

onMessage <*> (message update)

如果我使用return $ onMessage <*> (message update)包装表达式,则进行类型检查,但该函数似乎没有被评估。

如果我打开函数和参数并手动检查Nothing函数被调用但看起来很难看。

在此上下文中是否还有其他运算符?这些是我的第一个Monad Transformer步骤,这些类型太令人费解甚至尝试并提示答案。

...

type Bot a = ReaderT (BotConfig a) (StateT (BotState a) IO)

...

processUpdate :: Update -> Bot a ()
processUpdate update = do
    BotConfig {tw_handlers = MessageHandlers {
          tw_onMessage = onMg
        }
    } <- ask

    onMg <*> (message update) -- this is what I would like to do
                              -- onMg :: Maybe (Message -> Bot a ())
                              -- message :: Update -> Maybe Message

1 个答案:

答案 0 :(得分:2)

据你所说,我理解:

onMsg <*> (message update) :: Maybe ( Bot a () )

要执行随附的Bot a ()计算(如果它是Just),您可以使用:

maybe (return ()) id $ onMsg <*> (message update)

<强>更新

这是如何强迫&#34;评估包裹的Bot a ()计算?

我们知道onMsg <*> ...NothingJust comp,其中compBot a ()计算。

comp将被评估&#34;如果它成为do-block中monadic序列的一部分。

上面的代码与:

相同
case (onMsg <*> ...) of
  Nothing    -> return ()
  Just comp  -> comp

因此,return ()comp将是do-block的下一步。