I try to patternmatch on the Either type but I get an error. Why does the following work
patternMaster :: Either b b -> b
patternMaster (Right a) = a
patternMaster (Left a) = a
with patternMaster (Right a)
whereas I get the following output when I apply the function with its type mentioned just below:
<interactive>:40:63: error:
* Couldn't match expected type `ArithError'
with actual type `Integer'
* In the expression: a
In a case alternative: (Right a) -> a
In the expression:
case (evalErr (Cst 4) initEnvironment) of
(Left a) -> a
(Right a) -> a
-- -----------Types
initEnvironment :: Env
initEnvironment = \_v -> Nothing
-- --------Function
evalErr :: Exp -> Env -> Either ArithError Integer
evalErr (Cst e1) _ = Right e1
evalErr (Div e1 e2) env =
case evalErr e2 env of
Left az -> Left az
Right az ->
if az == 0
then Left EDivZero
else
case (evalErr e1 env) of
Left b -> Left b
Right b -> Right (b `div` az)
Shouldn't it be the same?
In this demo function:
patternMaster :: Either b b -> b
patternMaster (Right a) = a
patternMaster (Left a) = a
the input has to have the same type for the left and right alternatives, and patternMaster something
has that type as well. Eg
something
is Either Integer Integer
then patternMaster something
is Integer
something
is Either Integer String
then patternMaster something
does not compileMeanwhile your real code:
something =
case (evalErr (Cst 4) initEnvironment) of
(Left a) -> a
(Right a) -> a
what is the type of the case expression? If evalErr
evaluates, then it's Integer
. If evalErr
returns an error, then it's ArithError
. Those are incompatible types - there's no valid type for something
.
If you wanted to say it could be either Integer
or ArithError
, then you wouldn't have written this case statement and the overall type would be Either ArithError Integer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.