这种monad变压器类型意味着什么



看看文档中的内容:

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 IOa参数在哪里?

最后一件事——有人能解释一下如何运行这个monad吗?

文档的作者在记法方面反复无常。他们用它们的构造函数替换类型ErrorTStateT,它们也有名称ErrorTStateT。(这有一定的道理,因为它们是newtypes。)作者试图指出的是,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 IOa参数在哪里?

ErrorT e是一个单声道转换器,这意味着它将单声道转换为其他单声道。君主总是有一种* -> *;monad变压器有一种CCD_ 22。CCD_ 23也是一个monad变换器。这里,StateT s被应用于IO以产生新的monad(其是用状态管理能力增强的IO),然后ErrorT e被应用于其以产生另一个monad(它是用错误处理能力增强的StateT s IO)。


有人能解释一下如何运行这个monad吗?

正如我上面提到的,ErrorAndStateWithIO e s a只是s -> IO (Either e a, s),它周围有几个newtype包装器。所以要运行它,你需要打开newtype,传递一个s,将其垂直放入IO计算中,并仔细检查结果。

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]

相关内容

最新更新