instance Monad (Either a) where
return = Left
fail = Right
Left x >>= f = f x
Right x >>= _ = Right x
this code frag in 'baby.hs' caused the horrible compilation error:
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.
why this happen? and how could I make this code compile ? thanks for any help~
i see. and i adjusted the code to see it compiles:
instance Monad (Either a) where
return = Right
Left a >>= f = Left a
Right x >>= f = f x
it compiles successfully! but...for a further more question:
instance Monad (Either a)
makes 'Either a' a monad and i got 'return = Right'...how could i get 'return = Left'? i've tried this but failed:
instance Monad (`Either` a) where
return = Left
Right a >>= f = Right a
Left x >>= f = f x
or: instance Monad (\x -> Either x a)
doesn't compile at all!
Most of the confusion stems from the fact Left and Right are used backwards. Considering only the type for return, its type from the Monad typeclass is as follows:
return :: (Monad m) => b -> m b
You're trying to define an instance for m
= Either a
, so return should have type:
return :: b -> Either a b
You're defining it as Left, which has type:
Left :: a -> Either a b
Note how the left hand side of the ->
differs.
forall b. b -> Either a b
, however Left has type forall c. a -> Either a c
. You probably want Right here.fail
should have type forall b. String -> Either a b
, however Right has type forall b. b -> Either a b
, so if b=String
that makes String -> Either a String
which does not fit.>>=
should have type Either a b -> (b -> Either a c) -> Either a c
however Right x >>= _ = Right x
always returns a value of type Either a b
, not Either a c
.Left x >>= f = f x
does not work because x has type a
, but f
has type b -> c
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With