Reading: Webster Ch. 7
Give a BNF grammar for the language ML patterns. Use the non-terminal symbol <pattern>
as the start symbol. Use the non-terminal symbols <name>
and <constant>
, without defining productions for them, for the appropriate parts of the language.
<pattern> ::= <singular> | <tuple>
<singluar> ::= <list> | <name> | <constant> | <cons>
<tuple> ::= ( <tuple-list> )
<tuple-list> ::= <pattern> , <tuple-list> | <pattern>
<list> ::= [ <singular> ] | []
<cons> ::= <name> :: <cons-list> | <constant> :: <cons-list>
<cons-list> <name> | <constant> | <cons>
Define a function member
of type ''a * ''a list -> bool
so that member(e, L)
is true if and only if e
is an element of the list L
.
fun member (_, []) = false
| member (e, x::xs) =
if e = x then true
else member(e, xs);
(* Examples *)
member (1, [1,2,3,4]);
member (1, []);
member (1, [2,3,4]);
Write a quicksort function of type in list -> int list. Here’s a review of the quicksort algorithm. First pick an element and call it the pivot. (The head of the list is an easy choice for the pivot.) Partition the rest of the list into two sublists, one with all the elements less than the pivot and another with all the elements not less than the pivot. Recursively sort the sublists. Combine the two sublists (and the pivot) into a final sorted list.
fun partition (pivot, nil) = (nil, nil)
| partition (pivot, first::rest) =
let
val (small, large) = partition (pivot, rest)
in
if first < pivot
then (first::small, large)
else (small, first::large)
end;
fun quickSort nil = nil
| quickSort [single] = [single]
| quickSort (first::rest) =
let
val (small, large) = partition(first, rest)
in
quickSort(small) @ [first] @ quickSort(large)
end;
(* Example *)
quickSort [1, 4, 2, 7, 11, 8, 5]
Make another version of your quicksort
function, but this time of type 'a list * ('a * 'a -> bool) -> 'a list
. The second parameters should be a function that performs the role of the <
comparison in your original function. (Hint: This should only require minor changes to your previous quicksort
definition).
Example functions:
fun icmp (a, b) = a < b;
fun rcmp (a : real, b) = a < b;
fun partition (pivot, nil, opLT) = (nil, nil)
| partition (pivot, first::rest, opLT) =
let
val (small, large) = partition (pivot, rest, opLT)
in
if opLT (first, pivot)
then (first::small, large)
else (small, first::large)
end;
fun quickSort (nil, opLT) = nil
| quickSort ([single], opLT) = [single]
| quickSort (first::rest, opLT) =
let
val (small, large) = partition(first, rest, opLT)
in
quickSort(small, opLT) @ [first] @ quickSort(large, opLT)
end;
fun icmp (a, b) = a < b;
fun rcmp (a:real, b) = a < b;
(* Example *)
quickSort ([1, 4, 2, 7, 11, 8, 5], icmp)
quickSort [1.0, 4.5, 2.3, 7.0, 11.1, 8.2, 5.9] rcmp