避免一般使用返回两个函数的函数的值限制错误

时间:2012-12-11 09:34:03

标签: f# type-inference fparsec

我想将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

我通常如何应对这种情况?

1 个答案:

答案 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的类型取决于传递的不同类型的解析器,例如pstringpfloat

FParsec教程有一个关于F# value restriction的部分,可能也会有所帮助。