Home > Enterprise >  Make function return different types haskell
Make function return different types haskell

Time:10-13

I am completely new to haskell. I need a function that either returns an operator or returns an error message in the form of a string. For context I am building a Monadic Parser which accept doubles.

term'::Parser Double
term' = factor' `chainl1` mulop

addop, mulop :: Parser (Double -> Double -> Double)
mulop = do symbol "^" 
           return (**)
            do symbol "*" 
               return (*)
            do symbol "/"
               return (/)

addop = do symbol " " 
           return ( )
            do symbol "-"
               return (-)

The code above works well for returning the operator, however when I try expand on this by adding the error message I get compilation errors. Below is what I am attempting.

mulop :: Either (Parser (Double -> Double -> Double)) (Parser String)
mulop = do symbol "^" 
            return Left (**)
            do symbol "*" 
               return Left (*)
            do symbol "/" 
               return Left (/)
            pure Right "ERROR MSG"

CodePudding user response:

That's only a single parser. It needs input to decide whether the output is an operator or an error-string. So the signature has to be

mulop :: Parser (Either (Double -> Double -> Double) String)

Actually there's something of a convention that when using Either as an exception-adding type, the error messages should be on the Left, so perhaps better make it

mulop :: Parser (Either String (Double -> Double -> Double))

In the implementation: be careful to get the syntax rules right. return and pure are just ordinary functions, not special keywords like return in procedural languages. So it needs to be return $ Left (**).

Also make sure you get the indentation right. I would align this thus:

mulop = do symbol "^" 
           return $ Right (**)
        do symbol "*" 
           return $ Right (*)
        do symbol "/" 
           return $ Right (/)
        pure (Left "ERROR MSG")

Alternatively, don't use do notation. You don't really need anything monadic here, you can instead use the <$ operator:

mulop = (Right (**) <$ symbol "^")
        (Right (*) <$ symbol "*")
        (Right (/) <$ symbol "/")
        pure (Left "ERROR MSG")
  • Related