Typical abstract syntax tree with a functional application

I am trying to write a typed abstract type of a syntax tree that can represent functions.

I still 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 this last line - am I really getting this problem wrong?

+5
source share
1 answer

, F # , () . , (GADT), F # ( Haskell OCaml). F #, , .

, , 'b . , , , Expr<'a, 'b>, .

F #, ( , exists 'b, ). , , , , :

// Represents an application that returns 'a but consists
// of an argument 'b and a function 'b -> 'a
type IApplication<'a> =
  abstract Appl<'b> : Expr<'b -> 'a> * Expr<'b> -> unit

and Expr<'a> = 
  // Constant just stores a value...
  | Constant    of 'a 
  // An application is something that we can call with an 
  // implementation (handler). The function then calls the
  // 'Appl' method of the handler we provide. As this method
  // is generic, it will be called with an appropriate type
  // argument 'b that represents the type of the argument.
  | Application of (IApplication<'a> -> unit) 

(fun (n:int) -> string n) 42, - :

let expr = 
  Application(fun appl -> 
    appl.Appl(Constant(fun (n:int) -> string n), 
              Constant(42)))

:

let rec eval<'T> : Expr<'T> -> 'T = function
  | Constant(v) -> v   // Just return the constant
  | Application(f) ->
      // We use a bit of dirty mutable state (to keep types simpler for now)
      let res = ref None
      // Call the function with a 'handler' that evaluates function application
      f { new IApplication<'T> with
            member x.Appl<'A>(efunc : Expr<'A -> 'T>, earg : Expr<'A>) = 
              // Here we get function 'efunc' and argument 'earg'
              // The type 'A is the type of the argument (which can be
              // anything, depending on the created AST)
              let f = eval<'A -> 'T> efunc
              let a = eval<'A> earg
              res := Some <| (f a) }
      res.Value.Value

, - , , . , F # Expr. (, )?

+10

All Articles