2

次のように、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>()

値制限エラーが解消できません。exprCLR 関数に変換することはできませんexprR

通常、この状況にどのように対処しますか?

4

1 に答える 1

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# 値の制限に関するセクションがあり、これも役立つ場合があります。

于 2012-12-11T10:55:34.207 に答える