为什么这不是正确的实现?
instance Monad Lock where
(Working False x) >>= _ = Working False x
(Working True x) >>= f = f x
GHC 吐出的错误是关于刚性类型变量的错误:
• Couldn't match type ‘a’ with ‘b’
‘a’ is a rigid type variable bound by
the type signature for:
(>>=) :: forall a b. Lock a -> (a -> Lock b) -> Lock b
at src/Computers.hs:32:22
‘b’ is a rigid type variable bound by
the type signature for:
(>>=) :: forall a b. Lock a -> (a -> Lock b) -> Lock b
at src/Computers.hs:32:22
Expected type: Lock b
Actual type: Lock a
我可能误解了该错误,但从我有限的理解来看,编译器实际上要求我吐出不同的参数化类型,而不是相同的类型。
我尝试添加一个不带类型参数的不同构造函数(并仅为测试更改语义) - 然后它工作正常:
instance Monad Lock where
Broken >>= _ = Broken
(Working False x) >>= _ = Broken
(Working True x) >>= f = f x
编辑: 事实上,Lock的定义是:
data Lock a = Working Bool a
最佳答案
我假设您对 Lock
的定义如下所示:
data Lock a = Working Bool a
现在,让我们看看 (>>=)
的类型:
(>>=) :: Lock a -> (a -> Lock b) -> Lock b
这里重要的是,(>>=)
的调用者(而不是实现者)可以选择 a
和 的值>b
;例如,我可能会像使用它一样使用它:
(>>=) :: Lock Int -> (Int -> Lock Bool) -> Lock Bool
现在很清楚为什么你的实现不正确:在
Working False int >>= _ = Working False int
您将返回一个Lock Int
而不是Lock Bool
。
关于haskell - Monad Bind 坚持不同的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38382214/