I am creating a Computation Expression (CE) for simplifying the definition of Plans for modelers. I want to define functions that are only available in the CE. In this example the compiler says that the custom operations step
and branch
are being used incorrectly but I don't see why. All the compiler is saying is that they are not used correctly.
Note I know that I could define
step
andbranch
outside of the CE to accomplish this. This question is explicitly about using Custom Operators. I want to isolate this logic so that it is only available in the context of the CE.
type Step =
| Action of string
| Branch of string list list
type Plan =
{
Name : string
Steps : Step list
}
type PlanBuilder () =
member _.Yield _ =
{
Name = ""
Steps = []
}
member _.Run state = state
[<CustomOperation "name">]
member _.Name (state, name) =
{ state with Name = name }
[<CustomOperation "steps">]
member _.Steps (state, steps) =
{ state with Steps = steps }
[<CustomOperation "step">]
member _.Step (state, step) =
Action step
[<CustomOperation "branch">]
member _.Branch (state, branch) =
Branch branch
let plan = PlanBuilder ()
let x =
plan {
name "Chicken"
steps [
// The compiler reports errors for all the
// `step` and `branch` calls
step "1"
step "2"
branch [
[
step "3a"
step "4a"
]
[
step "3b"
step "4b"
]
]
step "5"
]
}
The error that is reported for step
is
FS3095: 'step' is not used correctly. This is a custom operation in this query or computation expression.
I.e.:
It's because you're inside of the list at this point. The CE keywords only work directly at the "top level" of a CE, as far as I'm aware.
You could make a "sub" CE for the individual step and put keywords in there e.g.
plan {
name "Chicken"
steps [
// The compiler reports errors for all the
// `step` and `branch` calls
step { name "1" }
step { name "2" }
branch [
[
step { name "3a" }
step { name "4a" }
]
]
]
}
etc.