I am trying to write a typed abstract syntax tree datatype that can represent
function application.
So far I have
type Expr<'a> =
| Constant of 'a
| Application of Expr<'b -> 'a> * Expr<'b> // error: The type parameter 'b' is not defined
I don’t think there is a way in F# to write something like ‘for all b’ on that last line – am I approaching this problem wrongly?
In general, the F# type system is not expressive enough to (directly) define a typed abstract syntax tree as the one in your example. This can be done using generalized algebraic data types (GADTs) which are not supported in F# (although they are available in Haskell and OCaml). It would be nice to have this in F#, but I think it makes the language a bit more complex.
Technically speaking, the compiler is complaining because the type variable
'bis not defined. But of course, if you define it, then you get typeExpr<'a, 'b>which has a different meaning.If you wanted to express this in F#, you’d have to use a workaround based on interfaces (an interface can have generic method, which give you a way to express constraint like
exists 'bwhich you need here). This will probably get very ugly very soon, so I do not think it is a good approach, but it would look something like this:To represent an expression tree of
(fun (n:int) -> string n) 42, you could write something like:A function to evaluate the expression can be written like this:
As I said, this is a bit really extreme workaround, so I do not think it is a good idea to actually use it. I suppose the F# way of doing this would be to use untyped
Exprtype. Can you write a bit more about the overall goal of your project (perhaps there is another good approach)?