顺序不对,见谅。这次作业挺难,最后也只得了80分,我就对着答案改了一下。挑战作业依旧不会,标准答案也没给出。
exception NoAnswer
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
fun g f1 f2 p =
let
val r = g f1 f2
in
case p of
Wildcard => f1 ()
| Variable x => f2 x
| TupleP ps => List.foldl (fn (p,i) => (r p) + i) 0 ps
| ConstructorP(_,p) => r p
| _ => 0
end
fun check_pat p=
let fun helper1 p=case p of Variable x =>[x]
| TupleP ps =>List.foldl(fn(p,i)=>i@(helper1 p)) [] ps
| ConstructorP(_,p)=>helper1 p
| _ =>[]
fun helper2 lst=case lst of []=>true
| x::xs =>(not(List.exists (fn y=>x=y) xs)) andalso helper2(xs)
in (helper2 o helper1) p
end
datatype typ = Anything
| UnitT
| IntT
| TupleT of typ list
| Datatype of string
fun count_some_var(str,p)=g (fn()=>0) (fn x=>if(x=str)then 1 else 0) p
fun count_wild_and_variable_lengths p=g (fn()=>1) String.size p
fun count_wildcards p=g (fn ()=>1) (fn _=>0) p
fun only_capitals strs=List.filter (Char.isUpper o (fn str=>String.sub(str,0))) strs
fun longest_string1 strs=foldl (fn (str,str0)=>if String.size str>String.size str0 then str else str0) "" strs
fun longest_string2 strs=foldl (fn (str,str0)=>if String.size str>=String.size str0 then str else str0) "" strs
fun longest_string_helper f=fn strs=>foldl (fn (str,str0)=>if f(str,str0) then str else str0) "" strs
val longest_string3=longest_string_helper (fn (str,str0)=>String.size str>String.size str0)
val longest_string4=longest_string_helper (fn (str,str0)=>String.size str>=String.size str0)
val longest_capitalized=longest_string1 o only_capitals
val rev_string =String.implode o List.rev o String.explode
fun first_answer f=fn lst=>case lst of
[]=>raise NoAnswer
| x::xs =>case f(x) of
SOME v=>v
| NONE =>first_answer f xs
fun all_answers f lst=
case lst of
[]=>SOME []
| x::xs =>(case f(x) of SOME v=>(case all_answers f xs of NONE=>NONE
| SOME i =>SOME(v@i))
| NONE =>NONE)
fun another_all_answers f lst=
let fun helper(acc,xs)=
case xs of
[]=>SOME acc
| x::xs' =>case f x of
NONE=>NONE
| SOME v =>helper((acc@v),xs')
in
helper([],lst)
end
fun match(v,p)=case(v,p) of (_,Wildcard)=>SOME []
| (_,Variable s) =>SOME [(s,v)]
| (Unit,UnitP) =>SOME []
| (Const a,ConstP b) =>if a=b then SOME [] else NONE
| (Tuple vs,TupleP ps) =>if(length vs=length ps)
then all_answers match (ListPair.zip(vs,ps))
else NONE
| (Constructor(s2,v'),ConstructorP(s1,p')) =>if s1=s2
then match(v',p')
else NONE
|_ =>NONE
fun first_match v ps=SOME(first_answer(fn p=>match(v,p)) ps)
handle NoAnswer=>NONE