Home > Blockchain >  How do I get the named fields in haskell correctly?
How do I get the named fields in haskell correctly?

Time:01-17

I am writing a parser with the help of parsec and I have a problem

data Param = Param {paramName::String, argument :: Maybe String}
  deriving (Show)

paramExpr1 :: Parser Param
paramExpr1 = do
  paramKeyword
  void $ lexeme $ char '-'
  paramName <- word
  return $ Param paramName Nothing 

paramExpr3 :: Parser Param
paramExpr3 = do
  pN  <- paramExpr1 -- <- PROBLEM HERE
  return $ Param pN Nothing 

In short, I don't understand how to get the named field, paramExpr1 will return Param and I would like to get paramName, but I don't understand how

CodePudding user response:

You can extract the field by using the field name as a function:

paramExpr3 :: Parser Param
paramExpr3 = do
  pN <- paramExpr1
  return $ Param (paramName pN) Nothing 

Alternatively, instead of creating a new value using the constructor Param, you can use the record update syntax and change the fields you want to change while leaving the others as they are.

paramExpr3 :: Parser Param
paramExpr3 = do
  pN <- paramExpr1
  return pN{ argument = Nothing }

More alternatives exist (e.g. using lenses), but these are the most basic approaches.

CodePudding user response:

Parser is a functor, so you can map a function over a parser to apply the function to whatever the parser will produce.

paramExpr3 :: Parser Param
paramExpr3 = do
    pName <- fmap parserName parseExpr1 -- turn a Parser Param into a Parser String
    return $ Param pName Nothing

If you had a function of type Param -> Param that replaced the existing argument field with Nothing

toNothing :: Param -> Param
toNothing (Param n _) = Param n Nothing

you could map that directly over the parsers.

parseExpr3 :: Parser Param
parseExpr3 = fmap toNothing parseExpr1
  • Related