type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let add<'a> (x: 'a) (y: 'a) (in_: Interpreter<'a>): 'a =
match in_ with
| RegularInterpreter r ->
x+y |> r
| StringInterpreter r ->
sprintf "(%s + %s)" x y |> r
The error message that he cannot solve 'aat compile time is completely clear to me. I guess the answer to the question of whether the above work can be done is not just adding functions directly to the data type. But then I could use the interface or completely get rid of the general parameters.
Edit: Mark the answer, really do what I asked, but let me ask the question, as I did not explain it properly. What I'm trying to do is to do with the above technique, mimics what was done in this post . The motivation for this is to avoid built-in functions, since they have poor compositional ability - they cannot be transmitted as lambda without specialized arguments.
I was hoping I could get around it by passing a union type with a common argument to close, but ...
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let val_ x in_ =
match in_ with
| RegularInterpreter r -> r x
| StringInterpreter r -> r (string x)
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ + y in_ |> r
| StringInterpreter r ->
sprintf "(%A + %A)" (x in_) (y in_) |> r
let inline mult x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ * y in_ |> r
| StringInterpreter r ->
sprintf "(%A * %A)" (x in_) (y in_) |> r
let inline r2 in_ = add (val_ 1) (val_ 3) in_
r2 (RegularInterpreter id)
r2 (StringInterpreter id) // Type error.
This last line gives a type error. Is there any way around this? Although I would prefer that the functions were not built-in due to the limitations that they impose on the composition.