Last active
November 6, 2015 09:47
-
-
Save lambdahands/6d9d025a85c8ca16f0d7 to your computer and use it in GitHub Desktop.
Object Algebras in OCaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
* An OCaml implementation of object algebras, inspired from this article by Oleksandr Manzyuk: | |
* https://oleksandrmanzyuk.wordpress.com/2014/06/18/from-object-algebras-to-finally-tagless-interpreters-2/ | |
*) | |
module ObjectAlgebras = struct | |
(* We technically don't need these interfaces; | |
* added here to compare between the Java implementation *) | |
type 'a expAlg = < lit : int -> 'a; add : 'a -> 'a -> 'a > | |
type 'a mulAlg = < mul : 'a -> 'a -> 'a > | |
(* Eval implementations *) | |
class eval init = object | |
method eval: int = init | |
end | |
class evalexp = object | |
method lit n = new eval n | |
method add (x: eval) (y: eval) = new eval (x#eval + y#eval) | |
end | |
class evalmul = object | |
inherit evalexp | |
method mul (x: eval) (y: eval) = new eval (x#eval * y#eval) | |
end | |
(* View implementations *) | |
class view init = object | |
method view: string = init | |
end | |
class viewexp = object | |
method lit n = new view (string_of_int n) | |
method add (x: view) (y: view) = | |
let s = "(" ^ x#view ^ " + " ^ y#view ^ ")" | |
in new view s | |
end | |
class viewmul = object | |
inherit viewexp | |
method mul (x: view) (y: view) = | |
let s = "(" ^ x#view ^ " * " ^ y#view ^ ")" | |
in new view s | |
end | |
let () = | |
(* exp instances*) | |
let e1 f = f#add (f#lit 10) (f#lit 10) in | |
let v1 = (new evalexp |> e1)#eval in | |
let s1 = (new viewexp |> e1)#view in | |
(* mul instances*) | |
let e2 f = f#mul (f#lit 10) (f#lit 10) in | |
let v2 = (new evalmul |> e2)#eval in | |
let s2 = (new viewmul |> e2)#view | |
in Printf.printf "%s = %d\n" s1 v1; (* (10 + 10) = 20 *) | |
Printf.printf "%s = %d\n" s2 v2 (* (10 * 10) = 100 *) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment