Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Packed = struct
- type t =
- | A of int
- | B of string
- | C of int * int
- end
- module Unpacked = struct
- type _ t =
- | A : int t
- | B : string t
- | C : (int * int) t
- type 'b consumer = { apply : 'a. 'a t -> 'a -> 'b }
- type packed = T : 'a t * 'a -> packed
- end
- (* Here's some example client code. The client is
- * writing a library that loops over user input and
- * repeatedly hands off control to a callback with
- * the appropriate variant. We can do this with
- * allocation only in the C case.
- *)
- let consume (f : unit Unpacked.consumer) =
- let rec loop () =
- begin
- match read_line () with
- | "a" -> f.apply A (read_int ())
- | "b" -> f.apply B (read_line ())
- | "c" ->
- (* right-to-left, who gives a shit *)
- f.apply C (read_int (), read_int ())
- | _ -> assert false
- end;
- loop ()
- in loop ()
- (* And you can store it in a data structure like this: *)
- let () =
- let open Unpacked in
- let example =
- [ T (A, 3)
- ; T (B, "3")
- ; T (C, (1, 2))
- ] in
- List.iter (function
- | T (A, x) -> Printf.printf "%d\n" x
- | T (B, x) -> Printf.printf "%s\n" x
- | T (C, x) -> Printf.printf "%d %d\n" (fst x) (snd x))
- example
- module Unpacked2 = struct
- type (_, 'b) t =
- | A : (int -> 'b, 'b) t
- | B : (string -> 'b, 'b) t
- | C : (int -> int -> 'b, 'b) t
- type 'b consumer = { apply : 'a. ('a, 'b) t -> 'a }
- type 'b a_little_packed = T : ('a, 'b) t * ('a -> 'b) -> 'b a_little_packed
- type very_packed = { data : 'b. 'b a_little_packed }
- end
- let consume (f : unit Unpacked2.consumer) =
- let rec loop () =
- begin
- match read_line () with
- | "a" -> f.apply A (read_int ())
- | "b" -> f.apply B (read_line ())
- (* Holly shit It's curreid. It's curried I mean. *)
- | "c" -> f.apply C (read_int ()) (read_int ())
- | _ -> assert false
- end;
- loop ()
- in loop ()
- (* But how the ****** do you store it in a data structure? *)
- let () =
- let open Unpacked2 in
- let example =
- [ { data = T (A, fun f -> f 3) }
- ; { data = T (B, fun f -> f "3") }
- ; { data = T (C, fun f -> f 1 2) }
- ]
- in
- List.iter (fun x ->
- match (x.data : unit a_little_packed) with
- | T (A, f) -> f (Printf.printf "%d\n")
- | T (B, f) -> f (Printf.printf "%s\n")
- (* ???? its curried?????? *)
- | T (C, f) -> f (Printf.printf "%d %d\n"))
- example
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement