简体   繁体   中英

Patternmatching in Haskell with Either type

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

  • if something is Either Integer Integer then patternMaster something is Integer
  • if something is Either Integer String then patternMaster something does not compile

Meanwhile 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM