在Haskell的绑定运算符中使用return(>> =)

时间:2016-07-10 16:18:17

标签: haskell functional-programming monads

这是>>=

的类型
(>>=) :: Monad m => m a -> (a -> m b) -> m b

它需要一个函数作为第二个参数。

以下是return的类型:

return :: Monad m => a -> m a

返回m a

这显然是类型检查:

(>>) :: Monad m => m a -> m b -> m b
x >> y = x >>= (\_ -> y)

但是为什么以下类型检查并与上面的代码类似?

(>>) :: Monad m => m a -> m b -> m b
x >> y = x >>= return y

此处return y应该是m a类型,而不是a -> m a。那它为什么有用呢?

2 个答案:

答案 0 :(得分:5)

你实际上在这里混合了两个不同的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)

return实例中实现Monad (a->)

instance Monad (->) a where
  return x = \_ -> x
  ...

它与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。只有在这一点上,编译器才会真正选择return的monad实例,并且通过观察a -> m b确实具有μ α形式,μ ~ (a->)和{{α ~ m b来实现这一点。 1}}。因此,它必须是(a->) monad。

答案 1 :(得分:4)

有一个函数的monad实例,其returnreturn x = \_ -> x(或等效return = const)。

因此,当您执行return y预期函数时,它只会选择函数monad的return