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绑定

posted @ 2018-04-03 11:18  lan126  阅读(224)  评论(0编辑  收藏  举报