haskell - few more monad - Error on the wall
in the module called "Control.Monad.Error" , it has defined a type called Error, adn that type hass been made an instance of the Monad (Either e), and the definition of that is
instance (Error e) => Monad (Either e) where return x = Right x Right x >>= f = f x Left err >>= f = Left err fail msg = Left (strMsg msg)
before we going to the details of the instance definition, we will first check the types of the Either type.
ghci> :t Right 4 Right 4 :: (Num t) => Either a t ghci> :t Left "out of cheese error" Left "out of cheese error" :: Either [Char] b
so the left type is often denoted as the error type and the right is dnoted as the result type. and there is no strong correlation between the left side and the right side.(we might be able to see the implication very soon)..
the return function just will return a result wrapped in the Either type. (this is straightforward) the right x when feeded to the f (a -> Monad b) will apply the function on the result contained in it, otherwise, if the value feed is a Left value (an error condition), then Left error is returned disregarding the function being applied. and there is a fail method, and it delegate the work to the strMsg function, what that does is to take an error in the form os string and return such a value (we can check the result type of strMsg as follow) .
ghci> :t strMsg strMsg :: (Error a) => String -> a ghci> strMsg "boom!" :: String "boom!"
But since we usually use String to describe the error when using Either, we don't have to worry about this too much!, when a pattern match fails in do notation, a Left value is used to signify this failure.
Below is an example of the usage.
ghci> Left "boom" >>= \x -> return (x+1) Left "boom" ghci> Right 100 >>= \x -> Left "no way!" Left "no way!"
but, as we said that the type parameter of Either is irrelevant, so that there is some implication on its use, here is the example.
ghci> Right 3 >>= \x -> return (x + 100) <interactive>:1:0: Ambiguous type variable `a' in the constraints: `Error a' arising from a use of `it' at <interactive>:1:0-33 `Show a' arising from a use of `print' at <interactive>:1:0-33 Probable fix: add a type signature that fixes these type variable(s)
so, you have to explicitly add the type signature.
ghci> Right 3 >>= \x -> return (x + 100) :: Either String Int Right 103