| instance Monad Parser where
| p >>= f = Parser (\state -> case ((unParser p) state) of
| all@(Error _ _ _ _) -> all
| Success v newState -> (unParser (f v)) newState
| )
|
| Haskell complains with
| Type checking
| ERROR "Parser1.hs" (line 28): Declared type too general
| *** Expression : (>>=)
| *** Declared type : Parser a -> (a -> Parser b) -> Parser b
| *** Inferred type : Parser a -> (a -> Parser a) -> Parser a
| because it assumes that the 'all' binding which is of type 'ParRes a'
| is not equivalent with 'ParRes b' although the Error constructor
| does not contain the parameter a at all. This works fine:
|
| instance Monad
| Parser where
| p >>= f = Parser (\state -> case ((unParser p) state) of
| Error msg x y s -> Error msg x y s
| Success v newState -> (unParser (f v)) newState
| )
| Is this the right behavior or rather a simplification in the type checker?
It is the correct behaviour, and the reasons that you give are correct also.
A value of type "ParRes a" cannot also be a value of type "ParRes b" unless
"a" and "b" are the same (even if you happen to know that, at runtime, the
value concerned is completely independent of either "a" or "b").
Mark