Search the haskell list

So, I have this calculator that I am creating that accepts user input variables like "let a = 2". These variables are stored in a list of tuples (variable, value). I need help getting data from this list. My code so far

primary :: Parser Float
primary = do symbol "("
         e <- expression
         symbol ")"
         return e
       +++ do v <- identifier                 
              let a = (find (==(head v)) vlist)
              return a

      

I am getting an error because find returns a Maybe value and I need it to return a Float or give the user an error message. How to do it?

+3


source to share


2 answers


I'm not sure where it comes from vlist

. It should probably be part of the user state of the parser. For now, let's assume this is the top-level definition:

vlist :: [(String, Float)]
vlist = undefined -- fill in the blanks...

      

I assume you are using Parsec

. You can simplify your parser:

primary :: Parser Float
primary = choice [ between (symbol "(") (symbol ")") expression
                 , do { ident <- identifier
                      ; case lookup ident vlist of
                          Nothing -> fail $ "No such identifier: " ++ ident
                          Just v -> return v
                      }
                 ]

      



You have several options for solving this problem. Here I used the parader monad function fail

. This will cause the parser to return a value Left parserError

. Alternatively, you can replace error

with fail

, which will result in an error that can only be handled in a monad IO

.

Note . To add vlist

a parser as a state, you need to define a new parser type with this state:

data MyParserState = MyParserState { vlist :: [(String, Float)] }
type MyParser = CharParser MyParserState

-- these parsers now need to return MyParser type!
symbol :: String -> MyParser String
identifier :: MyParser String
expression :: MyParser Float

primary :: MyParser Float
primary = choice [ between (symbol "(") (symbol ")") expression
                 , do { st <- getState
                      ; ident <- identifier
                      ; case lookup ident $ vlist st of
                          Nothing -> fail $ "No such identifier: " ++ ident
                          Just v -> return v
                      }
                 ]

      

+3


source


Perhaps run it through a block case x of

like this:



case find x of (Just y) -> --your code here
               Nothing  -> error "Wrong"

      

0


source







All Articles