【发布时间】:2019-03-27 02:57:53
【问题描述】:
我刚开始学习haskell,我正在尝试实现一些常见的单子作为自己的练习。当我摆弄((->) r) monad 时,我实现了这个(错误的)定义:
instance Monad ((->) r) where
return x = \_ -> x
m >>= f = \c -> (f . m) c
GHCi 向我抱怨
• Couldn't match expected type ‘b’ with actual type ‘t -> b’
`b’ is a rigid type variable bound by
the type signature for:
(>>=) :: forall a b. (t -> a) -> (a -> t -> b) -> t -> b
而类型应该是:
(>>=) :: (t -> a ) -> (a -> t -> b) -> t -> b
为什么我的实现会破坏它?看起来,forall 版本应该给出完全相同的类型,但 GHCi 不这么认为。有什么区别?
【问题讨论】:
-
你在哪里看到存在量化?
-
@melpomene 抱歉,如果我使用了错误的术语。我的定义中没有使用存在量化,但 GHC 认为类型签名包括
forall a b. -
提示:在
m >>= \x -> f x中,m需要r,但f x也是如此。 -
为什么你的
>>=有非标准类型?您是否定义了自己的>>=并翻转了参数? -
forall无关紧要。错误消息显示所有类型变量的显式声明,但(>>=) :: (a -> t -> b) -> (t -> a) -> t -> b的含义完全相同。真正的问题是类型应该是(>>=) :: (t -> a) -> (a -> t -> b) -> t -> b(即(>>=) :: (Monad m) => m a -> (a -> m b) -> m b和m = ((->) t))。为什么不是?