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