Commit 8d75a1b7 authored by James R. Wilcox's avatar James R. Wilcox
Browse files

materials from L12

parent 07b14108
; next topic: implementing records, variants, and pattern matching
; big difference between ocaml and trefoil: lack of type checking
;
; records in ocaml
; type myrecord = { name: str, present: bool }
; let x: myrecord = { name = "hello"; present = true } ; build
; x.name ; use
;
; introduce any PL feature (in a typed language)
; - how to write down the type
; - how to build values
; - how to use values
;
; introduce any PL feature (in an untyped language)
; - how to build values
; - how to use values
; declare the struct
; introduces a bunch of bindings into the environment
; - the constructor:
; - function of the same name as the type
; - takes one argument per field, in the order they were declared
; - field access functions
; - for each field:
; - define a new function called "typename-fieldname"
; - takes one argument, which should be a value of this struct type
; - returns the value of the corresponding field
; - if the argument has the wrong type, signal runtime error
(struct myrecord name present)
; constructor: (myrecord x y)
; 1st field access function: (myrecord-name r)
; 2nd field access function: (myrecord-present r)
; build values
(define r (myrecord "hello" true))
; use values
; - field access functions
(myrecord-name r) ; return "hello"
(myrecord-name (+ 1 2)) ; runtime error: myrecord-name applied to non-myrecord value
(myrecord-present r) ; return true
;;;;;;;
; even though you could do this with cons/car/cdr (if there are only two field)
; you can't mix cons and myrecord (or any struct)
;;;;;;;
;;;;;;;
; variants
;;;;;;;
; variants in OCaml
;
; ; declare
; type pizza = Cheese | Custom of string
;
; ; build
; Cheese
; Custom ("my instructions on the best pizza")
;
; ; use
; p has type pizza
; match p with
; | Cheese -> "cheese"
; | Custom msg -> "a custom pizza: " ^ msg
;;;;;;;;;;;;;;;;;;;
;
; for each constructor of the variants, declare a separate trefoil struct
(struct cheese) ;; generates constructor function, and 0 field access functions
(struct custom msg) ;; generates constructor function and 1 field access functions
; build
(cheese)
(custom "instructions for the best pizza ever")
; use
(define (f p)
; like to match on p
(custom-msg p) ; might throw an error if p was built with (cheese) constructor
)
; on monday we will add functions to check what kind of struct a value was built with
\ No newline at end of file
let x = (1, 2, 3)
let y =
match x with
| (a, b, c) -> a + b + c
let z =
let (a, b, c) = x in
a + b + c
let sum_triple((tr: int * int * int)): int =
let (a, b, c) = tr in
a + b + c
let sum_triple2(a, b, c): int =
a + b + c
let d = sum_triple((1, 2, 3))
let e = sum_triple(1, 2, 3)
let f = sum_triple2((1, 2, 3))
let g = sum_triple2(1, 2, 3)
let rotate_left_triple(a, b, c) = (b, c, a)
let rotate_right_triple(tr) = rotate_left_triple(rotate_left_triple(tr))
let rec rev(l: 'a list): 'a list =
match l with
| [] -> []
| x :: xs -> rev(xs) @ [x]
(* linear time, constant stack space implementation of reverse *)
let rev2(l: 'a list): 'a list =
let rec loop((l: 'a list), (acc: 'a list)): 'a list =
match l with
| [] -> acc
| x :: xs -> (* call loop tail recursively *)
loop(xs, x :: acc)
in
loop(l, [])
(* exceptions in ocaml *)
exception MyException
exception MyOtherException of string * int
(* raise exceptions (aka throw) *)
let oh_no () =
raise MyException
let oh_no_with_args () =
raise (MyOtherException ("hello", 17))
(* catch exceptions using "try ... with ..." *)
let catch_example () =
try
oh_no ()
with
MyException -> "caught!"
let catch_example_with_args () =
try
oh_no_with_args ()
with
MyOtherException (s, n) -> "caught info: " ^ s ^ " " ^ Int.to_string n
let catch_example_multiple b =
try
if b
then
oh_no ()
else
oh_no_with_args ()
with
| MyException -> "caught MyException"
| MyOtherException (s, n) -> "caught info: " ^ s ^ " " ^ Int.to_string n
let catch_all b =
try
if b
then
oh_no ()
else
oh_no_with_args ()
with
| _ -> "caught something"
let catch_all3 b =
try
if b
then
oh_no ()
else
oh_no_with_args ()
with
| e -> e
(* failwith is a normal function in the standard library, defined like this: *)
(*
exception Failure of string
let failwith msg = raise (Failure msg)
*)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment