我想将FParsec createParserForwardedToRef函数与通用的Expr联合一起使用,如下所示:
type Expr<'Term> =
| Unary of Operator * Expr<'Term>
| Binary of Operator * Expr<'Term> * Expr<'Term>
| Ternary of Operator * Expr<'Term> * Expr<'Term> * Expr<'Term>
| Term of 'Term
let expr, exprR = createParserForwardedToRef<Expr<'T>,unit>()
我无法摆脱价值限制错误。我无法将expr
转换为CLR函数,更不用说exprR
。
我通常如何应对这种情况?
答案 0 :(得分:5)
棘手的一点是通用Expr<'T>
。您可以创建一个返回expr
解析器的函数,然后让解析器的后续使用确定特定类型的Expr<'T>
:
let expr() =
// initially exprRef holds a reference to a dummy parser
let expr, exprRef = createParserForwardedToRef()
// create other union-case parsers as inner or outer functions
let unary() = ...
let binary = ...
let ternary() = ...
let term() = ...
// replace dummy parser reference in exprRef
do exprRef := choice [unary(); binary(); ternary(); term()]
expr
您还可以将term
等原始解析器作为expr
函数的参数传递。在这种情况下,expr
的类型取决于传递的不同类型的解析器,例如pstring
,pfloat
。
FParsec教程有一个关于F# value restriction的部分,可能也会有所帮助。