up to 12
This commit is contained in:
parent
a43a8271b3
commit
60656567c1
3 changed files with 210 additions and 4 deletions
|
@ -1,6 +1,20 @@
|
||||||
use "operators.sml";
|
use "operators.sml";
|
||||||
use "list.sml";
|
use "list.sml";
|
||||||
|
|
||||||
|
datatype pattern =
|
||||||
|
Wildcard
|
||||||
|
| Variable of string
|
||||||
|
| UnitP
|
||||||
|
| ConstP of int
|
||||||
|
| TupleP of pattern list
|
||||||
|
| ConstructorP of string * pattern
|
||||||
|
|
||||||
|
datatype valu =
|
||||||
|
Const of int
|
||||||
|
| Unit
|
||||||
|
| Tuple of valu list
|
||||||
|
| Constructor of string * valu
|
||||||
|
|
||||||
exception NoAnswer
|
exception NoAnswer
|
||||||
|
|
||||||
fun first str = String.sub (str, 0)
|
fun first str = String.sub (str, 0)
|
||||||
|
@ -37,7 +51,10 @@ fun first_answer f lst =
|
||||||
NONE => first_answer f tail
|
NONE => first_answer f tail
|
||||||
| SOME answer => answer
|
| SOME answer => answer
|
||||||
|
|
||||||
fun all_answers (f: ('a -> 'b list option)) lst: 'b list option =
|
fun all_answers
|
||||||
|
(f: ('a -> 'b list option))
|
||||||
|
(lst: 'a list)
|
||||||
|
: 'b list option =
|
||||||
let
|
let
|
||||||
fun collect lst acc =
|
fun collect lst acc =
|
||||||
case lst of
|
case lst of
|
||||||
|
@ -48,4 +65,59 @@ fun all_answers (f: ('a -> 'b list option)) lst: 'b list option =
|
||||||
| SOME lst => collect tail (acc @ lst)
|
| SOME lst => collect tail (acc @ lst)
|
||||||
in
|
in
|
||||||
collect lst []
|
collect lst []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fun sum a b = a + b
|
||||||
|
(* functions below are too similar to leave them as is.
|
||||||
|
Find a way how to extract reapiting code
|
||||||
|
*)
|
||||||
|
fun count_wildcards (p: pattern) : int =
|
||||||
|
case p of
|
||||||
|
Wildcard => 1
|
||||||
|
| TupleP lst => foldl (count_wildcards >> sum) 0 lst
|
||||||
|
| ConstructorP (_, pattern) => count_wildcards pattern
|
||||||
|
| _ => 0
|
||||||
|
|
||||||
|
fun collect_variables (p: pattern) : string list =
|
||||||
|
case p of
|
||||||
|
Variable str => [str]
|
||||||
|
| TupleP lst => foldl (collect_variables >> append) [] lst
|
||||||
|
| ConstructorP (_, pattern) => collect_variables pattern
|
||||||
|
| _ => []
|
||||||
|
|
||||||
|
fun count_variable_lengths (p: pattern) : int =
|
||||||
|
p |> collect_variables |> foldl (size >> sum) 0
|
||||||
|
|
||||||
|
fun count_wild_and_variable_lengths (p: pattern) : int =
|
||||||
|
count_wildcards p + count_variable_lengths p
|
||||||
|
|
||||||
|
fun count_some_var (var, pattern) =
|
||||||
|
case pattern of
|
||||||
|
Variable v => if v = var then 1 else 0
|
||||||
|
| TupleP lst => foldl (fn p => fn acc => acc + count_some_var (var, p)) 0 lst
|
||||||
|
| ConstructorP (_, pattern) => count_some_var (var, pattern)
|
||||||
|
| _ => 0
|
||||||
|
|
||||||
|
fun check_pat (p: pattern) : bool =
|
||||||
|
p
|
||||||
|
|> collect_variables
|
||||||
|
|> sort bigger_or_equal
|
||||||
|
|> distinct
|
||||||
|
|
||||||
|
fun match (v: valu, p: pattern) : (string * valu) list option =
|
||||||
|
case (p, v) of
|
||||||
|
(Wildcard, _) => SOME []
|
||||||
|
| (Variable a, v) => SOME [(a, v)]
|
||||||
|
| (UnitP, Unit) => SOME []
|
||||||
|
| (ConstP c1, Const c2) => if c1 = c2 then SOME [] else NONE
|
||||||
|
| (TupleP ps, Tuple vs) => (vs, ps) |> ListPair.zip |> all_answers match
|
||||||
|
| (ConstructorP (s1, p), Constructor (s2, v)) =>
|
||||||
|
if s1 = s2 then match (v, p) else NONE
|
||||||
|
| _ => NONE
|
||||||
|
|
||||||
|
fun first_match
|
||||||
|
(v: valu)
|
||||||
|
(patterns: pattern list) :
|
||||||
|
(string * valu) list option =
|
||||||
|
SOME $ first_answer (fn p => match (v, p)) patterns
|
||||||
|
handle NoAnswer => NONE
|
|
@ -1,6 +1,17 @@
|
||||||
use "test.sml";
|
use "test.sml";
|
||||||
use "hw3.sml";
|
use "hw3.sml";
|
||||||
|
|
||||||
|
fun comp a b = a <= b
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ sort comp [1, 2] = [1, 2]
|
||||||
|
$ "sort: sorting"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ sort comp [1, 2, 1, 0, 4, 5, 2] = [0, 1, 1, 2, 2, 4, 5]
|
||||||
|
$ "sort: sorting x2"
|
||||||
|
|
||||||
val () =
|
val () =
|
||||||
assert
|
assert
|
||||||
|
@ -86,5 +97,101 @@ val () =
|
||||||
["a", "b"] = NONE
|
["a", "b"] = NONE
|
||||||
$ "all_answers: NONE on at least one NONE"
|
$ "all_answers: NONE on at least one NONE"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ count_wildcards Wildcard = 1
|
||||||
|
$ "count_wildcards: Wildcard"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ count_wildcards (TupleP [Wildcard, Wildcard]) = 2
|
||||||
|
$ "count_wildcards: TupleP"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ count_wildcards (ConstructorP ("wild", Wildcard)) = 1
|
||||||
|
$ "count_wildcards: ConstructorP"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ count_wild_and_variable_lengths (TupleP [Wildcard, Variable "var"]) = 4
|
||||||
|
$ "count_wild_and_variable_lengths: correct length"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
let
|
||||||
|
val input = (
|
||||||
|
"var",
|
||||||
|
TupleP [
|
||||||
|
Wildcard,
|
||||||
|
Variable "var",
|
||||||
|
ConstructorP (
|
||||||
|
"cons",
|
||||||
|
Variable "var")])
|
||||||
|
val expected = 2
|
||||||
|
in
|
||||||
|
assert
|
||||||
|
$ count_some_var input = expected
|
||||||
|
$ "count_some_var: count vars"
|
||||||
|
end
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ check_pat (TupleP [Variable "a", Variable "b"]) = true
|
||||||
|
$ "check_pat: true on distinct"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ check_pat (TupleP [Variable "a",ConstructorP ("cons", Variable "a")]) = false
|
||||||
|
$ "check_pat: false on same"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ match (Unit, Wildcard) = SOME []
|
||||||
|
$ "match: SOME [] on wildcard"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ match (Unit, Variable "var") = SOME [("var", Unit)]
|
||||||
|
$ "match: match with var"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ match (Unit, UnitP) = SOME []
|
||||||
|
$ "match: match with unit"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ match (Const 3, ConstP 3) = SOME []
|
||||||
|
$ "match: match with const"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ match (Tuple [Const 3], TupleP [Variable "var"]) = SOME [("var", Const 3)]
|
||||||
|
$ "match: match with tuple"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ match (Tuple [Const 3], TupleP [Variable "var"]) = SOME [("var", Const 3)]
|
||||||
|
$ "match: match with tuple"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
let
|
||||||
|
val arg = (Constructor ("c", Unit), ConstructorP ("c", Variable "var"))
|
||||||
|
val expect = SOME [("var", Unit)]
|
||||||
|
in
|
||||||
|
assert
|
||||||
|
$ match arg = expect
|
||||||
|
$ "match: match with Constructor"
|
||||||
|
end
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ first_match Unit [ConstP 17, Variable "v"] = SOME [("v", Unit)]
|
||||||
|
$ "first_match: finds match"
|
||||||
|
|
||||||
|
val () =
|
||||||
|
assert
|
||||||
|
$ first_match Unit [ConstP 17] = NONE
|
||||||
|
$ "first_match: handles exeption"
|
||||||
|
|
||||||
val () = complete ()
|
val () = complete ()
|
|
@ -11,8 +11,35 @@ fun foldl f acc lst =
|
||||||
|
|
||||||
fun reverse lst = foldl cons [] lst
|
fun reverse lst = foldl cons [] lst
|
||||||
|
|
||||||
(* wrong implementation *)
|
fun sort' f lst =
|
||||||
fun foldr f acc = foldl f acc >> reverse
|
case lst of
|
||||||
|
[] => []
|
||||||
|
| [one] => [one]
|
||||||
|
| first :: second :: rest =>
|
||||||
|
if f first second
|
||||||
|
then first :: sort' f (second :: rest)
|
||||||
|
else second :: sort' f (first :: rest)
|
||||||
|
|
||||||
|
(* only for sorted lists *)
|
||||||
|
fun distinct lst =
|
||||||
|
case lst of
|
||||||
|
[] => true
|
||||||
|
| [_] => true
|
||||||
|
| first :: second :: rest =>
|
||||||
|
if first = second
|
||||||
|
then false
|
||||||
|
else distinct (second :: rest)
|
||||||
|
|
||||||
|
(* simple recursive convergence *)
|
||||||
|
fun fix f g x =
|
||||||
|
if f g x = x
|
||||||
|
then x
|
||||||
|
else fix f g (f g x)
|
||||||
|
|
||||||
|
(* naive bubble sort *)
|
||||||
|
fun sort f x = fix sort' f x
|
||||||
|
|
||||||
|
fun foldr f acc lst = lst |> reverse |> foldl f acc
|
||||||
|
|
||||||
fun map f = foldr (f >> cons) []
|
fun map f = foldr (f >> cons) []
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue