gpt4 book ai didi

purescript - "undefined value, reference not allowed"解决方法

转载 作者:行者123 更新时间:2023-12-04 00:10:17 25 4
gpt4 key购买 nike

我正在寻找有关编译器错误消息的一些说明 The value of xyz is undefined here, so reference is not allowed. , 连同做符号。我没有设法概括这个例子,我只能给出我偶然发现这种行为的具体例子。对此感到抱歉。

使用 purescript-parsing ,我想编写一个接受嵌套多行注释的解析器。为了简化示例,每个评论都以 ( 开头, 以 ) 结尾并且可以包含 a , 或其他评论。一些示例:(a)((a))已接受,() , (afoo被拒绝。

以下代码导致错误 The value of comment is undefined here, so reference is not allowed.在线content <- string "a" <|> comment :

comment :: Parser String String
comment = do
open <- string "("
content <- commentContent
close <- string ")"
return $ open ++ content ++ close

commentContent :: Parser String String
commentContent = do
content <- string "a" <|> comment
return content

我可以通过在 content <- string "a" <|> comment 上方插入一行来消除错误据我所知,它根本不会改变生成的解析器:

commentContent :: Parser String String
commentContent = do
optional (fail "")
content <- string "a" <|> comment
return content

问题是:

  • 这里发生了什么?为什么额外的行有帮助?
  • 编译代码的非 hacky 方法是什么?

最佳答案

如果您手动对 do 进行脱糖,那么第二种情况起作用的原因会变得更加明显:

commentContent :: Parser String String
commentContent =
optional (fail "") >>= \_ ->
string "a" <|> comment >>= \content ->
return content

当以这种方式定义时,comment 引用在 lambda 内部,因此不会在 commentContent 的定义期间求值。

至于非 hacky 解决方案,我想它会涉及一些 fix 的使用。 fix 允许您定义递归解析器,例如:

myParser = fix \p -> do
... parser definition ....

其中 p 是对 myParser 的引用,您可以在其自身中使用。至于这里有相互递归解析器的情况,我不确定如何最好地使用 fix 解决它,我可以想到几个选项,但没有一个特别优雅。也许是这样的:

parens :: Parser String String -> Parser String String
parens p = do
open <- string "("
content <- p
close <- string ")"
return $ open ++ content ++ close

comment :: Parser String String
comment = parens commentContent

commentContent :: Parser String String
commentContent = fix \p -> do
content <- string "a" <|> parens p
return content

使用类似于奇怪的 do 情况的技巧并在其中一个解析器前面插入一个 Unit -> 可能会更容易,这样你就可以延迟递归引用,直到提供 Unit 值,例如:

comment :: Parser String String
comment = do
open <- string "("
content <- commentContent unit
close <- string ")"
return $ open ++ content ++ close

commentContent :: Unit -> Parser String String
commentContent _ = do
content <- string "a" <|> comment
return content

关于purescript - "undefined value, reference not allowed"解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36984245/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com