p
is to write #2 p
.
This style is not idiomatic or readable. The proper way to handle
this is by pattern matching, so
fun first (x, _) = x fun second (_, y) = yis preferred, and not
fun bogus_first p = #1 p fun bogus_second p = #2 p(These versions don't even type-check.) If your pair or tuple is not an argument to a function, use
val
to do the pattern matching:
val (x, y) = lookup_pair mumbleBut usually you can include matching in ordinary
fun
matching.
Points will be deducted on homework for using #1
,
#2
, and their friends.
option
, which lets you
handle it.
The definition of option
is
datatype 'a option = NONE | SOME of 'aand it is already defined when you start the interactive system. You need not and should not define it yourself.
Some examples
- datatype chesspiece = K | Q | R | N | B | P - type square = chesspiece option - val empty : square = NONE - val lower_left : square = SOME R - fun play piece = SOME piece : square; > val play = fn : chesspiece -> chesspiece option - SOME true; > val it = SOME true : bool option - SOME 37; > val it = SOME 37 : int option - SOME "fish" = SOME "fowl"; > val it = false : bool - SOME "fish" = NONE; > val it = false : bool - "fish" = NONE; ! Toplevel input: ! "fish" = NONE; ! ^^^^ ! Type clash: expression of type ! 'a option ! cannot be made to have type ! string
The option
type is covered in Ullman on pages 111-113,
208, etc.
Array
structure
in Chapter 7, he
doesn't cover the immutable Vector
structure except for a
couple of pages deep in Chapter 9.
Like an array, a vector
offers constant-time access to an array of elements, but a vector is not
mutable.
Because of its immutability, Vector
is often preferred.
It is especially flexible when initialized with
Vector.tabulate
.
Here's the signature:
signature VECTOR = sig eqtype 'a vector val maxLen : int val fromList : 'a list -> 'a vector val tabulate : int * (int -> 'a) -> 'a vector val length : 'a vector -> int val sub : 'a vector * int -> 'a val update : 'a vector * int * 'a -> 'a vector val concat : 'a vector list -> 'a vector val appi : (int * 'a -> unit) -> 'a vector -> unit val app : ('a -> unit) -> 'a vector -> unit val mapi : (int * 'a -> 'b) -> 'a vector -> 'b vector val map : ('a -> 'b) -> 'a vector -> 'b vector val foldli : (int * 'a * 'b -> 'b) -> 'b -> 'a vector -> 'b val foldri : (int * 'a * 'b -> 'b) -> 'b -> 'a vector -> 'b val foldl : ('a * 'b -> 'b) -> 'b -> 'a vector -> 'b val foldr : ('a * 'b -> 'b) -> 'b -> 'a vector -> 'b val findi : (int * 'a -> bool) -> 'a vector -> (int * 'a) option val find : ('a -> bool) -> 'a vector -> 'a option val exists : ('a -> bool) -> 'a vector -> bool val all : ('a -> bool) -> 'a vector -> bool val collate : ('a * 'a -> order) -> 'a vector * 'a vector -> order end