在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
答案 0 :(得分:2)
据你所说,我理解:
onMsg <*> (message update) :: Maybe ( Bot a () )
要执行随附的Bot a ()
计算(如果它是Just),您可以使用:
maybe (return ()) id $ onMsg <*> (message update)
<强>更新强>
这是如何强迫&#34;评估包裹的Bot a ()
计算?
我们知道onMsg <*> ...
是Nothing
或Just comp
,其中comp
是Bot a ()
计算。
comp
将被评估&#34;如果它成为do-block中monadic序列的一部分。
上面的代码与:
相同case (onMsg <*> ...) of
Nothing -> return ()
Just comp -> comp
因此,return ()
或comp
将是do-block的下一步。