【问题标题】:How do I get the named fields in haskell correctly?如何正确获取 haskell 中的命名字段?
【发布时间】:2023-01-16 23:30:23
【问题描述】:

我在 parsec 的帮助下编写解析器,但遇到问题

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 

简而言之,我不明白如何获取命名字段,paramExpr1 将返回 Param,我想获取 paramName,但我不明白如何

【问题讨论】:

  • 目前尚不清楚您真正想要什么。您想要名称,还是要在执行时生成名称的解析器?
  • 解析器没有命名字段,所以如果是前者,Parser Param 是错误的类型。您要么想要Parser String,要么想要Parser Param -&gt; String

标签: haskell


【解决方案1】:

您可以使用字段名称作为函数来提取字段:

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

或者,除了使用构造函数Param 创建新值,您还可以使用记录更新语法并更改您想要更改的字段,同时保留其他字段。

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

存在更多替代方案(例如使用镜头),但这些是最基本的方法。

【讨论】:

  • 哦,我正在尝试做类似 pN <- paramExpr1 {f1, f2} ` ` return $ Param f1 Nothing `
  • 你也可以试试Param{paramName=f1} &lt;- paramExpr1 ; return $ Param f1 Nothing。或者Param{paramName=f1 , argument=f2} &lt;- paramExpr1 ; return $ Param f1 Nothing
【解决方案2】:

解析器是仿函数,因此您可以将函数映射到它们之上。

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

如果您有一个 Param -&gt; Param 类型的函数,它将现有的 argument 字段替换为 Nothing

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

您可以将其直接映射到解析器上。

parseExpr3 :: Parser Param
parseExpr3 = fmap toNothing parseExpr1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    相关资源
    最近更新 更多