instance Monad (Either a) where
     return = Left
     fail = Right
     Left x >>= f = f x
     Right x >>= _ = Right x

此代码在“ baby.hs”中引起了可怕的汇编错误:

Prelude> :l baby
[1 of 1] Compiling Main             ( baby.hs, interpreted )

baby.hs:2:18:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
       the type signature for `return' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the expression: Left
In the definition of `return': return = Left
In the instance declaration for `Monad (Either a)'

baby.hs:3:16:
Couldn't match expected type `[Char]' against inferred type `a1'
  `a1' is a rigid type variable bound by
       the type signature for `fail' at <no location info>
  Expected type: String
  Inferred type: a1
In the expression: Right
In the definition of `fail': fail = Right

baby.hs:4:26:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
       the type signature for `>>=' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the first argument of `f', namely `x'
In the expression: f x
In the definition of `>>=': Left x >>= f = f x

baby.hs:5:31:
Couldn't match expected type `b' against inferred type `a'
  `b' is a rigid type variable bound by
      the type signature for `>>=' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the first argument of `Right', namely `x'
In the expression: Right x
In the definition of `>>=': Right x >>= _ = Right x
Failed, modules loaded: none.

为什么会发生这种情况?我该如何编译该代码?感谢您的帮助〜

我知道了。我调整了代码以查看它的编译:

instance Monad (Either a) where
     return = Right
     Left a >>= f = Left a
     Right x >>= f = f x

它成功编译!但是...还有更多问题:

instance Monad (Either a)

使“一个'a monad和我得到'return =正确'...我怎么能得到'return = weled'?我已经尝试过,但失败了:

instance Monad (`Either` a) where
     return = Left
     Right a >>= f = Right a
     Left x >>= f = f x

或:实例monad( x-> XA)

根本不编译!

有帮助吗?

解决方案

  1. 返回应该有类型 forall b. b -> Either a b, 但是,左有类型 forall c. a -> Either a c. 。您可能想在这里。
  2. fail 应该有类型 forall b. String -> Either a b, ,但是正确的类型 forall b. b -> Either a b, , 因此,如果 b=String 这使得 String -> Either a String 这不合适。
  3. >>= 应该有类型 Either a b -> (b -> Either a c) -> Either a c 然而 Right x >>= _ = Right x 总是返回类型的值 Either a b, , 不是 Either a c.
  4. Left x >>= f = f x 因为x有类型,所以不起作用 a, , 但 f 有类型 b -> c.

其他提示

大多数混乱源于左右事实。仅考虑返回的类型,其单本类型的类型如下:

return :: (Monad m) => b -> m b

您正在尝试定义一个实例 m = Either a, ,因此返回应该具有类型:

return :: b -> Either a b

您将其定义为左侧,其中具有类型:

Left :: a -> Either a b

注意如何 -> 有所不同。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top