programming language part a 第三周作业

终于赶在deadline之前把它做完了

(* Dan Grossman, Coursera PL, HW2 Provided Code *)

(* if you use this function to compare two strings (returns true if the same
   string), then you avoid several of the functions in problem 1 having
   polymorphic types that may be confusing *)
fun same_string(s1 : string, s2 : string) =
    s1 = s2

(* put your solutions for problem 1 here *)

(* you may assume that Num is always used with values 2, 3, ..., 10
   though it will not really come up *)
datatype suit = Clubs | Diamonds | Hearts | Spades
datatype rank = Jack | Queen | King | Ace | Num of int 
type card = suit * rank

datatype color = Red | Black
datatype move = Discard of card | Draw 

exception IllegalMove

(* put your solutions for problem 2 here *)

(*1*)
fun all_except_option(str,strlist) = 
    let
    fun contain [] = false
      | contain (x::xs) = same_string(str,x) orelse contain xs
    fun collection (sl,acc) =
        case sl of
        [] => acc
          | x::xs => if same_string(str,x) then collection(xs,acc) else collection(xs,x::acc)
    in
    if contain strlist then SOME (collection(strlist,[])) else NONE
    end


fun get_substitutions1(sub,s) =
    case sub of
    [] => []
      | head::tail => 
    let 
        val result = all_except_option(s,head)
    in
        case result of
        NONE => get_substitutions1(tail,s)
          | SOME sl => sl @ get_substitutions1(tail,s)
    end

fun get_substitutions2(sub,s) =
    let
    fun helper(sub,s,acc) =
        case sub of
        [] => acc
          | head::tail => 
        let 
            val result = all_except_option(s,head)
        in
            case result of
            NONE => helper(tail,s,acc)
              | SOME sl => helper(tail,s,sl@acc)
        end        
    in
    helper(sub,s,[])
    end

fun similar_names (sub,{first=f,middle=m,last=l}) =
    let
    val result = get_substitutions2(sub,f)
    fun generator (reslist,acc) =
        case reslist of
        [] => acc
          | head::tail => generator(tail,{first=head,middle=m,last=l}::acc)
    in
    {first=f,middle=m,last=l}::generator(result,[])
    end
    

(*2*)
fun card_color ca =
    case ca of
    (Clubs,_) => Black
     | (Spades,_) => Black
     | (Hearts,_) => Red
     | (Diamnods,_) => Red

fun card_value (_,ra) = 
    case ra of
    Num n => n
      | Ace => 11
      | _ => 10

fun remove_card (cs,c,e) =
    let
    fun contain [] = false
      | contain (x::xs) = (x = c) orelse contain xs
    fun collection (cl,acc,cnt) =
        case cl of
        [] => acc
          | x::xs => if ((x = c) andalso (cnt = 0)) then collection(xs,acc,cnt+1) else collection(xs,x::acc,cnt)
    in
    if (contain cs) then collection(cs,[],0) else raise e
    end
    
fun all_same_color cs =
    case cs of 
    [] => true
     | head::[] => true
     | head::mid::tl => ((card_color head) = (card_color mid)) andalso (all_same_color (mid::tl))

fun sum_cards cs =
    let 
    fun helper (cl,acc) =
        case cl of
        [] => acc
          | head::tail => helper(tail,acc+ card_value(head))
    in
    helper(cs,0)
    end

fun score (held,goal) =
    let
    val sum = sum_cards held
    val pre = if sum > goal then 3*(sum - goal) else goal - sum
    val rescore = if all_same_color(held) then pre div 2 else pre
    in
    rescore
    end

fun officiate (cl,ml,goal) =
    let               
    fun helper state = (*the first parameter is cardlist ,the second is movelist,the third heldlist*)
        case state of
        (_,[],held) => score(held,goal)
          | (cardlist,(Discard ca)::tail,held) => helper(cardlist,tail,remove_card(held,ca,IllegalMove))
          | ([],(Draw)::tail,held) => score(held,goal)
          | (h1::t1,(Draw)::tail,held) => 
        if sum_cards(h1::held) > goal then score(h1::held,goal) else helper(t1,tail,h1::held)
    in
    helper(cl,ml,[])
    end

 这一周主要的知识就是

pattern matching

tail recursion,tail position 一般递归优化成尾递归

case expression

用 nested pattern matching 去写 elegant的代码

以及用_来匹配不在意的位置

上述作业里面已经全部都涉及到了

sicp里面也讲过,sicp还教怎么实现

原文地址:https://www.cnblogs.com/tclan126/p/8640714.html