Due date: Friday, October 18th, 11:59PM
You must update the course software to get the support code for this assignment. From the terminal:
$ opam update $ opam install cs691f.1.3.2
In this assignment, you will write several little programs in System F. The support code includes a System F implementation which has several convenient features (e.g., top-level let bindings and the ability to give names to types). You don't need to implement System F yourself, though you're welcome read or change the code if you like.
Once you update the course software, you should have another executable
called systemf
alongside the cs691f
executable
that you used in previous assignments. Running it starts a System F
REPL. You can also store REPL commands to a file and do:
$ systemf filename.fThis executes filename.f and then enters the REPL.
Submit a file named solution.f with the following:
type ('a, 'b, 'c) triple = Triple of a * b * c
let triple_proj1 (t : ('a, 'b, 'c) triple) : 'a = match x with
| Triple (a, b, c) -> a
let triple_proj2 (t : ('a, 'b, 'c) triple) : 'b = match x with
| Triple (a, b, c) -> b
let triple_proj3 (t : ('a, 'b, 'c) triple) : 'c = match x with
| Triple (a, b, c) -> c
type ('a, 'b) either =
| Left of 'a
| Right of 'b
type bool =
| True
| False
/* Booleans */ type [[Bool]] = forall R . R -> R -> R;; let true = typfun R -> fun (x : R) -> fun (y : R) -> x;; let false = typfun R -> fun (x : R) -> fun (y : R) -> y;; let if = typfun R -> fun (cond : [[Bool]]) -> fun (true_branch : R) -> fun (false_branch : R) -> cond<R> true_branch false_branch;; let and = fun (e1 : [[Bool]]) -> fun (e2 : [[Bool]]) -> typfun R -> fun (x : R) -> fun (y : R) -> e1 <R> (e2 <R> x y) y;; let or = fun (e1 : [[Bool]]) -> fun (e2 : [[Bool]]) -> typfun R -> fun (x : R) -> fun (y : R) -> e1 <R> x (e2 <R> x y);;Implement the not, nand, and xor operators for booleans.
type 'a foo =
| Bar of 'a * 'a
| Baz
/* Lists and options */ type [[Option T]] = forall R . (T -> R) -> R -> R;; let some = typfun T -> fun (x : T) -> typfun R -> fun (some : T -> R) -> fun (none : R) -> some x;; let none = typfun T -> typfun R -> fun (some : T -> R) -> fun (none : R) -> none;; let option_case = typfun T -> typfun R -> fun (v : [[Option T]]) -> fun (some_case : T -> R) -> fun (none_case : R) -> v <R> some_case none_case;; type [[List T]] = forall R . (T -> R -> R) -> R -> R;; let cons = typfun T -> fun (hd : T) -> fun (tl : [[List T]]) -> typfun R -> fun (c : T -> R -> R) -> fun (n : R) -> c hd (tl <R> c n);; let empty = typfun T -> typfun R -> fun (c : T -> R -> R) -> fun (n : R) -> n;; /* An example list */ let example_list = cons<int> 100 (cons<int> 200 (cons<int> 300 (empty<int>)));;Implement the reverse function. Hint: First, write a function to add an element to the end of a list. This function is commonly called snoc.
/* Integer comparisons */ 10 = 10;; 50 = 1;; 10 < 5;; 10 > 5;;