Sea*_*azi 3 monads haskell functional-programming
这是以下类型>>=
:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
它需要一个函数作为第二个参数.
这是以下类型return
:
return :: Monad m => a -> m a
Run Code Online (Sandbox Code Playgroud)
返回 m a
这显然是类型检查:
(>>) :: Monad m => m a -> m b -> m b
x >> y = x >>= (\_ -> y)
Run Code Online (Sandbox Code Playgroud)
但为什么以下类型检查和工作类似于上面的代码?
(>>) :: Monad m => m a -> m b -> m b
x >> y = x >>= return y
Run Code Online (Sandbox Code Playgroud)
这return y
应该是类型m a
而不是a -> m a
.那它为什么有效呢?
你实际上在这里混合了两个不同的monad,这就是正在发生的事情.x >>= return y
在这种情况下统一到
(>>) :: ? m a b . Monad m => m a -> m b -> m b
x >> y = x >>= (return :: m b -> a -> m b) y
-- aka return :: (m b) -> (a->) (m b)
Run Code Online (Sandbox Code Playgroud)
在实例中return
实现的位置Monad (a->)
:
instance Monad (->) a where
return x = \_ -> x
...
Run Code Online (Sandbox Code Playgroud)
它与Monad m
实例没有任何关系.
至于为什么它return
在函数monad中运行:return :: m b -> a -> m b
在编译器开始推理类型类实例之前从环境推断出来.现在,类型m b -> a -> m b
,即m b -> (a->m b)
具有形式mb -> amb
.因此签名return :: Monad ? => ? -> ? ?
使编译器匹配? ? ~ amb ~ a->m b
.只有在这一点上,编译器才会真正选择monad实例return
,并且通过观察a -> m b
确实有形式? ?
,使用? ~ (a->)
和来实现? ~ m b
.因此,它必须是(a->)
monad.
归档时间: |
|
查看次数: |
210 次 |
最近记录: |