7

Using a custom operation of a f# computation expression inside any control flow statement fails typechecking with

error FS3086: A custom operation may not be used in conjunction with 'use',
'try/with', 'try/finally', 'if/then/else' or 'match' operators within this
computation expression

Why is this not allowed? What is in custom operation that does not allow rewriting this:

expr {
    if a then
        custom (x)
    else
        return (y)
}

to something like this:

expr {
    return! 
        if a then
            expr { custom (x) }
        else
            expr { return (y) }
}
pqnet
  • 6,070
  • 1
  • 30
  • 51
  • Look at http://www.readcopyupdate.com/blog/2014/10/10/edsls-using-custom-operations.html It seems that you are trying to use custom operations in a way they were not intended to be used. – jpe Oct 24 '17 at 13:08
  • @jpe i'm not sure what you mean by that, and not whether it is related. What is the intended use that i'm not doing? The link you posted does not explain that, it only shows an example of how it could be used (and I could tell it is not the "intended use" either - they were introduced to implement the `query` computation expression for linq). The question is anyway about another issue which is why this apparently simple translation is explicitly disabled in the compiler (is there some catch which I am not seeing?). – pqnet Oct 24 '17 at 14:35
  • As the error message tells you, you cannot use a custom operation in if/then/else (among other expressions). You can define your own `condition` operator, e.g. like in https://github.com/Apress/expert-fsharp-4.0/blob/master/ExpertFSharp-master/16Language/Script.fsx (look at how `condition`has been defined and used in `AttemptBuilder`). – jpe Oct 25 '17 at 07:44
  • The point seems to be in how the custom operation is actually handled. On p. 475 in Expert F# 4.0 there is a sentence that sheds some light into that: "Loosely speaking, a custom operation gets to operate on the 'whole' computation - any vaues already declared in the computation expression are packaged up into a tuple, the operation is applied , and the values are then unpackaged. The technique used to package and unpackage is either `return/let!` or `yield/for` (depending on `MaintainsVariableSpaceUsingBind` being `true` or `false`)". – jpe Oct 25 '17 at 08:42
  • but that's exactly my point. What prevent the `if`, `for`, `match` and similar statement to create a sub-computation (packaged and unpackaged with `let!/return` as you said) for that scope and let the custom operation operate on the whole sub-operation? – pqnet Oct 26 '17 at 10:09

0 Answers0