[英]Function composition hint
只是寻找解释以下组成如何工作:
(=<<) . return
哪里
(=<<) :: (a -> m b) -> m a -> m b
return :: a -> m a
(.) :: (b -> c) -> (a -> b) -> a -> c
最终类型:
GHCi> :t (=<<) . return
(=<<) . return :: Monad m => m b -> m a -> m b
我不知道如何匹配ma (a - > mb) ,即。 如何将一个简单类型的返回结果应用到期望函数类型的(= <<)的第一个参数?
解释是:
return
(或许意外)是与你的=<<
不同的monad。 (->) r
。 编译器试图统一的结果return :: c -> m' c
与第一个参数(a -> mb) -> ma -> mb
,所以统一 m' c
与a -> mb
。 唯一的可能性是m'
是某些r
的读者monad (->) r
r
。 接下来,它尝试将(->) rc
与(转换为前缀表示法) (->) a (mb)
统一起来,这通过将r
设置为a
和c
来设置为mb
来解决。 因此,在统一之后,编译器获得最通用的类型
return :: (m b) -> ((->) a (m b))
或者以通常的中缀表示法
return :: (m b) -> (a -> m b)
也可以看看:
Monad ((->) r)
实例的源 。 编辑:要定义一个单子,我们需要一个(部分应用)类型的一种 * -> *
。 这些几乎总是部分应用数据构造函数,但是在这种特殊情况下,我们查看->
作为一个类型操作符,它接受2个类型参数并创建一个新类型(函数类型)。 因此对于任何给定类型r
,部分应用的表达式(->) r
是一种类型* -> *
。 事实证明,如何在其上描述monad操作有一种简单的方法。 请参阅Control.Reader monad以及解释它的本文 。 Reader
的monad操作实现与(->)
完全相同,唯一的区别是Reader
将操作包装成不同的数据类型。
我再次与涂鸦一起并排放置东西以帮助视觉理解:
g = ((=<<) . return) {-
((=<<) . return) x y
=== (=<<) (return x) y return :: a' -> m' a'
(=<<) :: (a -> m b) -> m a -> m b return x :: m' a' , x :: a'
m' a' m' ~ ((->) a) , a' ~ m b
return x === const x -- instance Monad ((->) a) where return = const
g x y === y >>= (\_ -> x) === y >> x (!!)
-}
g :: m b -> m a -> m b
事实证明(并且可能从类型签名中可以看出), g === flip (>>)
:
Prelude> ((=<<).return) [1] "xyz" -- === (=<<) (const [1]) "xyz"
-- === "xyz" >>= const [1]
-- === "xyz" >> [1]
-- === (>> [1]) "xyz"
[1,1,1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.