練習問題 5.2 (つづき)

5. 2つの[a1; ...; an] と [a1; ...; bn] を引数として,[(a1,b1); ...; (an,bn)] を返す関数 zip (与えられたリストの長さが異なる場合は長いリストの余った部分を捨ててよい)。

 # let rec zip l1 l2 =
     match (l1, l2) with
       ([], _) -> []
     | (_, []) -> []
     | (h1::t1, h2::t2) -> (h1, h2) :: zip t1 t2
   ;;
 val zip : 'a list -> 'b list -> ('a * 'b) list = <fun>
 # zip [2; 3; 4; 5; 6; 7; 8; 9; 10; 11]
       [true; true; false; true; false; true; false; false; false; true];;
 - : (int * bool) list =
 [(2, true); (3, true); (4, false); (5, true); (6, false); (7, true);
  (8, false); (9, false); (10, false); (11, true)]

6. ペアのリスト [(a1,b1); ...; (an,bn)] を引数として,リストのペア ([a1; ...; an], [b1; ...; bn]) を返す関数 unzip。

 # let unzip l = (List.map fst l, List.map snd l);;
 val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>
 # unzip (zip [2;3;4;5;6;7;8;9;10;11]
              [true; true; false; true; false; true;
               false; false; false; true]);;
 - : int list * bool list =
 ([2; 3; 4; 5; 6; 7; 8; 9; 10; 11],
  [true; true; false; true; false; true; false; false; false; true])

7. リストと,リストの要素上の述語 p を満たすすべての要素のリストを返す関数 filter。

 # let rec filter p = function
     [] -> []
   | hd::tl when p hd -> hd :: filter p tl
   | hd::tl           -> filter p tl
   ;;
 val filter : ('a -> bool) -> 'a list -> 'a list = <fun>
 # filter (fun l -> List.length l =3) [[1;2;3]; [4;5]; [6;7;8]; [9]];;
 - : int list list = [[1; 2; 3]; [6; 7; 8]]

8. 先頭からn番目までの要素からなる部分リストを取り出す関数 take とn番目までの要素を抜かした 部分リストを取り出す drop

まず take。

 # let rec take n = function
     [] -> []
   | hd::tl -> if n = 0 then [] else hd :: take (n-1) tl
   ;;
 val take : int -> 'a list -> 'a list = <fun>
 # take 3 [1;2;3;4;5];;
 - : int list = [1; 2; 3]
 # take 0 [1;2;3;4;5];;
 - : int list = []

drop

 # let rec drop n = function
     [] -> []
   | hd::tl -> if n = 0 then hd::tl else drop (n-1) tl
   ;;
 val drop : int -> 'a list -> 'a list = <fun>
 # drop 3 [1;2;3;4;5];;
 - : int list = [4; 5]
 # drop 0 [1;2;3;4;5];;
 - : int list = [1; 2; 3; 4; 5]

9. (空でない)リストの中から最大値を返す関数 max_list。

 # let max_list l =
     let hd::tl = l in
     List.fold_left max hd tl
   ;;
 Characters 25-31:
 Warning P: this pattern-matching is not exhaustive.
 Here is an example of a value that is not matched:
 []
       let hd::tl = l in
           ^^^^^^
 val max_list : 'a list -> 'a = <fun>
 # max_list [5; 9; 0; -7];;
 - : int = 9

警告がでてるのは空リストに対応できてないからだろう。まぁ問題の答えにはなってるのでいいことにする。