haskell - Monad Bind 坚持不同的类型?

标签 haskell monads

为什么这不是正确的实现?

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/

相关文章:

loops - 使用 Haskell 读取 n 行输入

haskell - Writer monad 中的记忆化

Haskell 图像处理库?

haskell - Haskell 的序列函数问题

haskell - 状态单子(monad) haskell

haskell - 检查字符串是 Haskell 中不区分大小写的回文

haskell - 如何嵌套 monad

haskell - 如何在 Haskell 中使用 Monad 类的多个构造函数参数上映射函数?

haskell - 为什么 "bind"在 Haskell Monads 中写为 >>=?

haskell - 如何在 Haskell 中实现实际解​​析已经完成的 Read 实例?