【发布时间】:2019-04-06 23:53:19
【问题描述】:
我目前正在处理 monad 转换器并试图真正理解类型签名,但我有些困惑。让我们使用以下堆栈进行讨论:
newtype Stack s m a = Stack { runStack :: ReaderT s (StateT s IO) a }
我正在尝试逐层遍历并编写未包装的类型签名但卡住了:
newtype Stack s m a = Stack {
runStack :: ReaderT s (StateT s IO) a }
-- ReaderT s m a
-- s -> m a
-- s -> (StateT s IO) a
-- StateT s m a
-- s -> (s -> IO (a, s)) a
这看起来不像最后一行的有效返回类型签名,我们基本上有一个函数,它接受一个 s 并返回一个推向 a 的函数?
我得到内部函数最终评估为 Monad,这就是为什么它是 ReaderT r m a 中的 m,但它让我的大脑弯曲。
谁能提供任何见解,我是否正确分析了这些类型,我只需要接受s -> (s -> IO (a, s)) a 确实有效?
谢谢
【问题讨论】:
-
我们有
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }。既然如此,(StateT s IO) a归结为s -> IO (a,s),并且没有悬空的a。 -
@duplode ReaderT 返回的
a怎么样?newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }。因为IO (a,s)在元组中有a,所以它像我上面那样从最右边被删除了? -
"ReaderT 返回的
a怎么样?" -- 那是(StateT s IO) a中的a。请注意,ReaderT本身并不返回a,而是返回m a。 -
@duplode :mind-blast: 现在完全有道理了,哇非常感谢你帮我解决这个问题!!
标签: haskell functional-programming