pf_*_*les 5 monads haskell either
instance Monad (Either a) where
return = Left
fail = Right
Left x >>= f = f x
Right x >>= _ = Right x
Run Code Online (Sandbox Code Playgroud)
'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.
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我怎么能编译这个代码?谢谢你的帮助〜
我知道了.我调整了代码,看它编译:
instance Monad (Either a) where
return = Right
Left a >>= f = Left a
Right x >>= f = f x
Run Code Online (Sandbox Code Playgroud)
它编译成功!但是......还有一个问题:
instance Monad (Either a)
Run Code Online (Sandbox Code Playgroud)
使'要么是'一个单子而我得到'返回=正确'......我怎么能得到'return = Left'?我试过这个但失败了:
instance Monad (`Either` a) where
return = Left
Right a >>= f = Right a
Left x >>= f = f x
Run Code Online (Sandbox Code Playgroud)
或:实例Monad(\ x - >要么是xa)
根本不编译!
大多数混淆源于左和右向后使用的事实.仅考虑返回的类型,Monad类型类中的类型如下:
return :: (Monad m) => b -> m b
Run Code Online (Sandbox Code Playgroud)
您正在尝试为m= 定义实例Either a,因此返回应具有类型:
return :: b -> Either a b
Run Code Online (Sandbox Code Playgroud)
您将其定义为Left,其类型为:
Left :: a -> Either a b
Run Code Online (Sandbox Code Playgroud)
注意左侧是如何->不同的.
forall b. b -> Either a b,但是 Left 具有 type forall c. a -> Either a c。您可能想要就在这里。fail应该有 type forall b. String -> Either a b,但是 Right 有 type forall b. b -> Either a b,所以如果b=String这使得String -> Either a Stringwhich 不适合。>>=应该有 typeEither a b -> (b -> Either a c) -> Either a c但Right x >>= _ = Right x总是返回 type 的值Either a b,而不是Either a c。Left x >>= f = f x不起作用,因为 x 具有 type a,但f具有 type b -> c。