Avoiding value restriction error for generic use of function that returns two functions

StackOverflow https://stackoverflow.com/questions/13817302

  •  07-12-2021
  •  | 
  •  

문제

I want to use the FParsec createParserForwardedToRef function with a generic Expr union, like this:

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>()

I can't get rid of the value restriction error. I can't turn expr into a CLR function, much less exprR.

How would I normally deal with this situation?

도움이 되었습니까?

해결책

The tricky bit is the generic Expr<'T>. You can make a function that returns expr parser, and let subsequent use of parsers determine a specific type of 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

You could also pass primitive parsers such as term as arguments to expr function. In this case, type of expr depends on different kinds of parsers passed on e.g. pstring, pfloat.

FParsec tutorial has a section on F# value restriction which might also be helpful.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top