MonadTrans
上课法中有一些我不理解的内容。
lift . return
的类型为a -> t m a
return
的类型为a -> m a
lift . return = return
如何检查?
答案 0 :(得分:2)
鉴于某些monad t
上有一些monad变换器m
,m
和t m
都是monad。因此,return
可以实例化为a -> m a
或a -> t m a
。
在这种情况下,lift
的类型为m a -> t m a
。因此,如果我们为a -> m a
选择return
类型,则lift . return
的类型为a -> t m a
。这是return
的另一种可能的类型,因此等价的类型检查。
以下是用类型注释的整个等价:
(lift :: m a -> t m a) . (return :: a -> m a) = (return :: a -> t m a)
答案 1 :(得分:2)
首先:应该理解return
的{{1}}和m
的{{1}}是两个不同的函数,属于两个不同的实例。
函数组合return
的约定与通常的数学符号相同,即对于某些类型t m
,它必须包含f . g
和g : x -> y
。
文档非常清楚地表明f: y -> z
的类型是:
x, y, z
也就是说,只要找到lift
的{{1}},lift :: Monad m => m a -> t m a
基本上就是Monad
类型。
我们知道属于m
的{{1}}类型为lift
。
因此,类型m a -> t m a
和return
的两个函数m
和a -> m a
是可组合的,它们的组成是return
的{{1}}
答案 2 :(得分:1)
首先比较lift
和return
的类型:
return :: Monad m => a -> m a
lift :: (Monad m, MonadTrans t) => m a -> t m a
两者都做类似的事情:return
将任何类型的值提升为包装第一种类型的monadic类型。 lift
将已经包含在monad中的值提升到由monad转换器创建的另一个 monad中。由于原始monad m
和转换后的monad t m
都有自己的return
函数,因此您有两种方法可以将a
类型的值放入monad {{1} }}:
t m a
return :: a -> t m a
,然后return :: a -> m a
。交换图看起来像
lift :: m a -> t m a
第一个monad变换器法则规定,从 return
a -------> m a
\ |
\ | lift
return \ |
\ v
+------ t m a
到a
的路径无关紧要。