Skip to content

Instantly share code, notes, and snippets.

@amosr
Created February 18, 2017 00:26
Show Gist options
  • Save amosr/982c138e0d9ec3bd5b7363fa00f36c69 to your computer and use it in GitHub Desktop.
Save amosr/982c138e0d9ec3bd5b7363fa00f36c69 to your computer and use it in GitHub Desktop.
simplified schema
(* Schema and value definitions *)
type schema
= SInt
| SBool
| SArray of schema
type value
= VInt of int
| VBool of bool
| VArray of value list
type file = int list
(* Load a "file" for given schema *)
exception LoadError of schema;;
let rec load_file_go (s : schema) (xs : file) : value * file =
match s, xs with
| SInt , x :: xs
-> VInt x, xs
| SBool , x :: xs
-> VBool (x != 0), xs
| SArray s, x :: xs
-> let rec go i vs xs =
match i with
| 0 -> VArray (List.rev vs), xs
| _ -> let (v,xs) = load_file_go s xs in
go (i-1) (v :: vs) xs
in go x [] xs
| _, []
-> raise (LoadError s)
;;
let load_file (s : schema) (f : file) : value =
match load_file_go s f with
| v, [] -> v
| _, x::xs -> raise (LoadError s)
;;
assert (VArray [VInt 10; VInt 20] = load_file (SArray SInt) [2; 10; 20]);;
assert (VArray [VBool true; VBool false] = load_file (SArray SBool) [2; 1; 0]);;
(* Some arbitrary operation we want to perform on the values *)
let rec value_twiddle (v : value) : value =
match v with
| VInt i -> VInt (i + 1)
| VBool b -> VBool (not b)
| VArray vs -> VArray (List.map value_twiddle vs)
;;
assert (VInt 1 = value_twiddle (VInt 0));;
assert (VBool true = value_twiddle (VBool false));;
assert (VArray [VInt 1; VInt 2] = value_twiddle (VArray [VInt 0; VInt 1]));;
(* Writing back to file *)
let rec write_file (v : value) : file =
match v with
| VInt i -> [i]
| VBool b -> [if b then 1 else 0]
| VArray vs -> List.length vs :: List.concat (List.map write_file vs)
;;
assert ([2; 1; 0] = write_file (VArray [VBool true; VBool false]));;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment