type ErrorAndStateWithIO e s a = ErrorT e (StateT s IO) a
==> ErrorT (StateT s IO (Either e a))
==> ErrorT (StateT (s -> IO (Either e a,s)))
我还附加了ErrorT
的构造函数:
Constructors
ErrorT
runErrorT :: m (Either e a)
我无法理解的事情就是我的帖子。这是什么意思?对我而言,这意味着ErrorT e (StateT s IO) a = ErrorT (StateT s IO (Either e a))
。这是怎么回事?它类似于自动调用构造函数(runErrorT
)?
困扰我的第二件事:我们知道StateT
的形式为StateT s m a
。在这里,我们有StateT s IO
。 a
参数在哪里?
最后一件事 - 有人可以解释如何运行这个monad吗?
答案 0 :(得分:1)
文档的作者用符号快速而松散地播放。他们正在使用其构造函数替换类型ErrorT
和StateT
,这些构造函数的名称为ErrorT
和StateT
。 (这有点道理,因为他们只是newtype
。)作者试图提出的观点是ErrorAndStateWithIO e s a
等同于s -> IO (Either e a, s)
;它周围只有几个newtype
包装器。
查看这些类型的定义,
newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) }
newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
你可以看到,在第一步中,外部ErrorT
已被其定义所取代,而在第二步中,内部StateT
已被其定义所取代。
在这里,我们有
StateT s IO
。a
参数在哪里?
ErrorT e
是monad transformer,这意味着它会将monad转换为其他monad。 Monads总是有一种* -> *
; monad变形金刚有一种(* -> *) -> (* -> *)
。 StateT s
也是monad变换器。在这里,StateT s
被应用于IO
以生成新的monad(IO
增强了状态管理功能),然后ErrorT e
正在应用于StateT s IO
生成另一个monad(ErrorAndStateWithIO e s a
增加了错误处理功能)。
有人可以解释如何运行这个monad吗?
正如我上面提到的,s -> IO (Either e a, s)
只是newtype
,其周围有几个newtype
包装。因此,要运行它,您需要打开s
,传入myComputation :: ErrorAndStateWithIO String Int Char
myComputation = -- ...
main = do
(result, _) <- runStateT (runErrorT myComputation) 5
case result of
Left err -> putStrLn err
Right result -> putStrLn $ "Success: " ++ [result]
,将其转换为IO计算并仔细检查结果。
query-threads