programming language part a 第四周作业
代码
(* Coursera Programming Languages, Homework 3, Provided Code *)
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
(**** for the challenge problem only ****)
datatype typ = Anything
| UnitT
| IntT
| TupleT of typ list
| Datatype of string
(**** you can put all your code here ****)
(*val is closure fun is function*)
(*1*)
val only_capitals = List.filter (fn x => (Char.isUpper o String.sub)(x,0))
(*2*)
val longest_string1 = foldl (fn (acc,x) => if String.size acc > String.size x then acc else x) ""
(*3*)
val longest_string2 = foldl (fn (acc,x) => if String.size acc >= String.size x then acc else x) ""
(*4*)
fun longest_string_helper cmp = foldl (fn (x,y) => if cmp(String.size x,String.size y) then x else y) ""
val longest_string3 = longest_string_helper (fn (x,y) => x > y)
val longest_string4 = longest_string_helper (fn (x,y) => x >= y)
(*5*)
val longest_capitalized = longest_string1 o only_capitals
(*6*)
val rev_string = implode o List.rev o explode
(*7*) (*if we can find it then stop else recursive*)
fun first_answer f lt =
case lt of
[] => raise NoAnswer
| head::tail => case f head of SOME v => v
| NONE => first_answer f tail
(*8*)
(*
fun all_answers f lt =
let
val new = foldl (fn (x,y) => case f x of SOME v => v @ y | NONE => y) [] lt
in
if length new <> length lt then NONE else SOME new
end
*)
fun all_answers f xs =
let fun loop (acc,xs) =
case xs of
[] => SOME acc
| x::xs' => case f x of
NONE => NONE
| SOME y => loop((y @ acc), xs')
in loop ([],xs) end
(*9a*)
val count_wildcards = g (fn () => 1) (fn x => 0)
(*9b*)
val count_wild_and_variable_lengths = g (fn () => 1) (fn x => String.size x)
(*9c*)
fun count_some_var (st,p) = g (fn () => 0) (fn x => if st = x then 1 else 0) p
(*10*)
val check_pat =
let
fun coll inn_p =
case inn_p of
Variable x => [x]
| TupleP ps => foldl (fn (x,y) => (coll x) @ y) [] ps (***********)
| ConstructorP(_,np) => coll np
| _ => []
fun isrep sl =
case sl of
[] => false
| head::tail => List.exists (fn x:string => x = head) tail orelse isrep tail
in
not o isrep o coll
end
(*11*)
fun match vandp =
case vandp of
(va,Variable s) => SOME [(s,va)]
| (Const i1,ConstP i2) => if i1 = i2 then SOME [] else NONE
| (Unit,UnitP) => SOME []
| (Tuple vs,TupleP ps) => if length vs = length ps then (all_answers match (ListPair.zip(vs,ps))) else NONE
| (Constructor(s1:string,v),ConstructorP(s2,p)) => if s1 = s2 then match(v,p) else NONE
| (_,Wildcard) => SOME []
| _ => NONE
(*12*)
fun first_match v ps= SOME (first_answer (fn p => match(v,p)) ps) handle NoAnswer => NONE
知识点
First-Class Function
就是函数可以当做数据来传入一个函数或者作为函数的返回值
匿名函数
真是个好东西
词法作用域
词法作用域就是函数调用时所使用的环境为函数定义时所使用的环境
闭包
闭包就是一种数据,它包括代码和该函数所处作用域数据的绑定
Combining Fuction
通过 o 操作符来组合函数,避免函数嵌套,代码更加优雅
map filter fold
currying
将多参函数转换成单参函数的技术
Partial Application
提高代码的复用率
如何使用函数式编程实现ADT
实现一个集合
Mutable 和 callback
用val绑定函数和用fun绑定函数的区别是前者不能处理递归情况后者可以
val绑定一个函数,如果必须在绑定时传一个参数那么得用fun绑定
Yosoro