1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-01-17 21:49:22 +01:00

Add notes about records to Standard ML page.

This commit is contained in:
inaimathi 2015-06-06 12:51:45 -04:00
parent 9e44a5b9ee
commit 152c03ddf9

View File

@ -4,6 +4,7 @@ contributors:
- ["Simon Shine", "http://shine.eu.org/"] - ["Simon Shine", "http://shine.eu.org/"]
- ["David Pedersen", "http://lonelyproton.com/"] - ["David Pedersen", "http://lonelyproton.com/"]
- ["James Baker", "http://www.jbaker.io/"] - ["James Baker", "http://www.jbaker.io/"]
- ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
--- ---
Standard ML is a functional programming language with type inference and some Standard ML is a functional programming language with type inference and some
@ -136,9 +137,29 @@ val mixup = [ ("Alice", 39),
val good_bad_stuff = val good_bad_stuff =
(["ice cream", "hot dogs", "chocolate"], (["ice cream", "hot dogs", "chocolate"],
["liver", "paying the rent" ]) (* string list * string list *) ["liver", "paying the rent" ]) (* : string list * string list *)
(* Records are tuples with named slots *)
val rgb = { r=0.23, g=0.56, b=0.91 } (* : {b:real, g:real, r:real} *)
(* You don't need to declare their slots ahead of time. Records with
different slot names are considered different types, even if their
slot value types match up. For instance... *)
val Hsl = { H=310.3, s=0.51, l=0.23 } (* : {H:real, l:real, s:real} *)
val Hsv = { H=310.3, s=0.51, v=0.23 } (* : {H:real, s:real, v:real} *)
(* ...trying to evaluate `Hsv = Hsl` or `rgb = Hsl` would give a type
error. While they're all three-slot records composed only of `real`s,
they each have different names for at least some slots. *)
(* You can use hash notation to get values out of tuples. *)
val H = #H Hsv (* : real *)
val s = #s Hsl (* : real *)
(* Functions! *) (* Functions! *)
fun add_them (a, b) = a + b (* A simple function that adds two numbers *) fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
val test_it = add_them (3, 4) (* gives 7 *) val test_it = add_them (3, 4) (* gives 7 *)
@ -225,17 +246,26 @@ fun fibonacci 0 = 0 (* Base case *)
| fibonacci 1 = 1 (* Base case *) | fibonacci 1 = 1 (* Base case *)
| fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *) | fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *)
(* Pattern matching is also possible on composite types like tuples and lists. (* Pattern matching is also possible on composite types like tuples, lists and
Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on the one records. Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on
three-tuple solve2 takes as argument. Similarly, but less intuitively, you the one three-tuple solve2 takes as argument. Similarly, but less intuitively,
can match on a list consisting of elements in it (from the beginning of the you can match on a list consisting of elements in it (from the beginning of
list only). *) the list only). *)
fun first_elem (x::xs) = x fun first_elem (x::xs) = x
fun second_elem (x::y::xs) = y fun second_elem (x::y::xs) = y
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
| evenly_positioned_elems [odd] = [] (* Base case: throw away *) | evenly_positioned_elems [odd] = [] (* Base case: throw away *)
| evenly_positioned_elems [] = [] (* Base case *) | evenly_positioned_elems [] = [] (* Base case *)
(* When matching on records, you must use their slot names, and you must bind
every slot in a record. The order of the slots doesn't matter though. *)
fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
(* If called with {r=0.1, g=0.2, b=0.3}, either of the above functions
would return (0.1, 0.2, 0.3). But it would be a type error to call them
with {r=0.1, g=0.2, b=0.3, a=0.4} *)
(* Higher order functions: Functions can take other functions as arguments. (* Higher order functions: Functions can take other functions as arguments.
Functions are just other kinds of values, and functions don't need names Functions are just other kinds of values, and functions don't need names