Created
October 31, 2018 16:20
-
-
Save bracevac/149ea2654103d8668fb9e5e6b4dd5d98 to your computer and use it in GitHub Desktop.
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
type _ trep = .. | |
type _ trep += | |
| TInt: int trep | |
| TString: string trep | |
| TFloat: float trep | |
| TList: 'a trep -> 'a list trep | |
| TFun: ('a trep * 'b trep) -> ('a -> 'b) trep | |
(* Emulating type classes *) | |
module ShowClass = struct | |
type _ key = .. | |
effect Show: ('a key * 'a) -> string | |
effect Resolve: 'a trep -> 'a key | |
let resolve trep = | |
perform (Resolve trep) | |
let show trep s = | |
perform (Show (perform (Resolve trep),s)) | |
end | |
module IntShow = struct | |
type _ ShowClass.key += Key : int ShowClass.key | |
let handler action = | |
try action () with | |
| effect (ShowClass.Resolve TInt) c -> | |
continue c Key | |
| effect (ShowClass.Show (Key, x)) c -> | |
continue c (Printf.sprintf "%d" x) | |
end | |
module ListShow = struct | |
(* The formation of key constructors reflects type class constraints *) | |
type _ ShowClass.key += Key : 'a ShowClass.key -> 'a list ShowClass.key | |
let rec format k xs = match xs with | |
| [] -> "" | |
| x :: [] -> perform (ShowClass.Show (k, x)) | |
| x :: xs -> Printf.sprintf "%s;%s" (perform (ShowClass.Show (k, x))) (format k xs) | |
let handler action = | |
try action () with | |
| effect (ShowClass.Resolve (TList trep)) c -> | |
continue c (Key (ShowClass.resolve trep)) | |
| effect (ShowClass.Show (Key k, xs)) c -> | |
continue c (Printf.sprintf "[%s]" (format k xs)) | |
end | |
let context action = IntShow.handler (fun () -> ListShow.handler action) | |
let demo () = ShowClass.show (TList TInt) [1;2;3] | |
let _ = context demo | |
;; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment