Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何调用部分取消嵌套的转换器?_Haskell_Monads_Monad Transformers - Fatal编程技术网

Haskell 如何调用部分取消嵌套的转换器?

Haskell 如何调用部分取消嵌套的转换器?,haskell,monads,monad-transformers,Haskell,Monads,Monad Transformers,给定变压器嵌套:T2/T1/M0,如何利用:T2/M0,::M2? 这里有一个例子:我正在编写一些需要读取、记录和状态的函数。定义: gameRoutine :: WriterT [String] (ReaderT Env (State Viable)) NUM 如果我想打电话 stateFunction::State-available-NUM 甚至是stateWithReaderFunction::ReaderT Env(State available)NUM 我可以使用电梯: gameR

给定变压器嵌套
:T2/T1/M0
,如何利用
:T2/M0
::M2

这里有一个例子:我正在编写一些需要读取、记录和状态的函数。定义:

gameRoutine :: WriterT [String] (ReaderT Env (State Viable)) NUM
如果我想打电话
stateFunction::State-available-NUM

甚至是
stateWithReaderFunction::ReaderT Env(State available)NUM

我可以使用电梯:

gameRoutine = do
    x <- lift . lift $ stateFunction
    y <- lift $ stateWithReaderFunction
gameRoutine=do

基本上,
mtl
的想法是你不需要这样做。您不是使用该特定签名定义
writerStateFunction
,而是使用通用签名定义它

writerStateFunction' :: (MonadWriter [String] m, MonadState Viable m)
          => m NUM
那么,您尝试使用它的环境是否有一个额外的
读卡器
层并不重要:这不会阻止monad同时具有
MonadWriter
MonadState
功能。

您可以通过以下方式将
Writer w
提升到实例中:

import Control.Monad.Writer (MonadWriter, Writer, runWriter, tell)

lift' :: MonadWriter w m => Writer w a -> m a
lift' wr = do
    let (a, w) = runWriter wr
    tell w    -- manually re-log the log msg
    return a  -- wrap value into new context
然后,你可以简单地写下:

gameRoutine :: WriterT [String] (ReaderT Env (State Viable)) NUM
gameRoutine = do
    a <- lift' writerFunction
gameRoutine::WriterT[String](ReaderT-Env(State-available))NUM
gameRoutine=do

谢谢你的回答,让我大吃一惊。但是,如何使用
writerStateFunction'
?我需要更改
gameRoutine
定义吗?我不知道什么类型与约束匹配
(MonadWriter[String]m,MonadState-m)
。这怎么可能?在我的理解中,一个转换器包装了一个单子,是一个单子,但为什么它实际上继承了内在单子的“特征”?当然还有很多东西需要学习。@IlyaSmagin对于任何
Monad m
(以及另一个Monad转换器中的任何一种类型),类型
WriterT[String](StateT m available)NUM
StateT available(WriterT m[String])NUM都与该约束匹配!这就是全部要点——您实际上只是实例化不同类型的值以获得不同的顺序(不同的顺序为某些转换器提供了不同的语义!)。您描述的“继承”正是
mtl
的机制-我建议使用@leftaroundabout ok将尝试阅读:)编译器需要
-XFlexibleContexts
,所以这一定是一些狡猾的黑客行为,对吧?@IlyaSmagin:FlexibleContexts
没有太多黑客行为,这是一个扩展,你可以打开一点担心;它基本上只是禁用了标准Haskell的一些限制,这使得编写编译器变得更容易;但GHC不需要这个。当它请求
可重叠的
或者甚至
不连贯的
时,您应该对此保持警惕。。。