What is the difference between "err @ (Left _)" and "Left err"
I am trying to use codes from <Real World Haskell>.
In GHC version 6.10.4:
data ParseState = ParseState {
string :: String
} deriving (Show)
newtype Parse a = Parse {
runParse :: ParseState -> Either String (a, ParseState)
}
parse :: Parse a -> String -> Either String a
parse parser initState =
case runParse parser (ParseState initState) of
Left err -> Left err
Right (result, _) -> Right result
Everything went fine until I changed "Left err" to "err @ (Left _)":
-- err@(Left _) -> err
{-
- Occurs check: cannot construct the infinite type:
- a = (a, ParseState)
- When generalising the type(s) for `parse'
-}
Any ideas?
This is subtle. casechecks the type value Either String (a, ParseState), so when you call the template in
err@(Left _) -> err
errhas the same type. However, the return type of the function says that it should be Either String athat does not match the type err Either String (a, ParseState). Looking at the type Left:
Left :: x -> Either x y
When you use Leftthe right side in
Left err -> Left err
y, a (a, ParseState).
, , , .
, Control.Arrow ( (->) ) :
left :: (a -> a') -> Either a b -> Either a' b
right :: (b -> b') -> Either a b -> Either a b'
(+++) :: (a -> a') -> (b -> b') -> Either a b -> Either a' b'
(: , , ). , :
parse parser = right fst . runParse parser . ParseState