ml演習 第 - 東京大学sgotou/lecture/caml-enshu/...o'caml...

56
ML演習 第 2 2007/06/12 飯塚 大輔, 後藤 哲志, 前田 俊行

Upload: others

Post on 12-Aug-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

ML演習 第 2 回

2007/06/12飯塚 大輔, 後藤 哲志, 前田 俊行

Page 2: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

2

今日の内容

パターンマッチ リスト型 Parametric Polymorphism ユーザ定義型

レコード型 バリアント型

多相データ型

Page 3: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

3

今日の内容

パターンマッチ リスト型 Parametric Polymorphism ユーザ定義型

レコード型 バリアント型

多相データ型

Page 4: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

4

パターンマッチとは?

値の 「パターン」 で処理を分岐させること # let rec fib n = match n with 0 | 1 -> 1 | x -> fib (x - 1) + fib (x – 2);; val fib : int -> int = <fun>

Page 5: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

5

パターンの種類

定数パターン 変数束縛パターン OR パターン ペアパターン コンストラクタパターン (リストなど (後述)) ワイルドカード

Page 6: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

6

定数パターン 定数と比較, 一致すれば OK

変数束縛パターン 任意の値にマッチ マッチした値は本体中で使用可能 # let rec pow x n = match n with 0 -> 1 | m -> x * pow x (m – 1);; val pow : int -> int -> int = <fun>

パターンの種類

Page 7: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

7

パターンの種類

ORパターン 複数のパターンのうち一つでもマッチすれば OK # let rec fib n = match n with 0 | 1 -> 1 | x -> fib (x – 1) + fib (x – 2);; val fib : int -> int = <fun>

Page 8: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

8

パターンの種類

Tuple パターン Tuple の要素それぞれがマッチすれば OK 変数束縛パターンと組合わせて要素の取出しが可能 # let scalar n p = match p with (x, y) -> (n * x, n * y);; val scalar : int -> int * int -> int * int # scalar 3 (2, 3);; - : int * int = (6, 9)

Page 9: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

9

パターンの種類

ワイルドカード ( _ ) 任意の値にマッチ

マッチした値が計算に使われないことを明示している # let is_vowel x =

match x with

'a' | 'e' | 'i' | 'o' | 'u' -> true

| _ -> false;;

val is_vowel : char -> bool = <fun>

Page 10: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

10

ガード

パターンに条件を追加する仕組み # let is_diag p = match p with (x, y) when x = y -> true | _ -> false;; val is_diag : 'a * 'a -> bool = <fun> # is_diag (3, 3);; - : bool = true # is_diag (3, 4);; - : bool = false

Page 11: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

11

関数定義におけるパターンマッチ

let (rec) や fun の仮引数部分にはパターンを書ける

# let thd (_, _, z) = z;; val thd : 'a * 'b * 'c -> 'c = <fun> # thd (3, true, "hoge");; - : string = "hoge" # fun n (x, y) -> (n * x, n * y);; - : int -> int * int -> int * int = <fun>

Page 12: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

12

関数定義におけるパターンマッチ

function式: 引数を 1 個受け取りパターンマッチを行う関数を作る

# let rec fib = function 0 | 1 -> 1 | x -> fib (x – 1) + fib (x – 2);; val fib : int -> int = <fun> # let rec pow x = function 0 -> 1 | n -> x * pow x (n – 1);; val pow : int -> int -> int = <fun>

Page 13: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

13

マッチできない値があるとき

警告が出る # let flip x = match x with 0 -> 1 | 1 -> 0;; Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: 2 val flip : int -> int = <fun> # flip 2;; Exception: Match_failure ("", 1, 13).

2が来たときに対応するパターンがない

パターンマッチに失敗

一応定義はされる

Page 14: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

14

パターンを書く上での注意

1 つのパターン中に同じ変数を2 回以上使うことはできない

# let is_diag p = match p with (x, x) -> true | _ -> false;; This variable is bound several times in this

matching.

xを2回使用

Page 15: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

15

パターンを書く上での注意

OR でつながったそれぞれのパターンでは束縛する変数が一致しなければならない

# let f p = match p with (1, x, y) | (2, x, _) -> x;; Variable y must occur on both sides of this |

pattern.

| の右側でyが束縛されていない

Page 16: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

16

今日の内容

パターンマッチ リスト型 Parametric Polymorphism ユーザ定義型

レコード型 バリアント型

多相データ型

Page 17: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

17

リストの基本要素

空リスト ([]) # [];; - : 'a list = []

Cons セル (::) # 1 :: [];; - : int list = [1] # 1 :: (2 :: (3 :: []));; - : int list = [1; 2; 3]

Page 18: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

18

型に関する注意

リストの要素はすべて同じ型でなければならない

# [1; 2; 3];; - : int list = [1; 2; 3] # [1; true; "hoge"];; Characters 4-8: [1; true; "hoge"];; ^^^^ This expression has type bool but is here used with type int.

Page 19: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

19

リストの操作

cons (::) と append (@) を使ったリスト操作

# let l1 = [1; 2; 3];; val l1 : int list = [1; 2; 3] # -1 :: 0 :: l1;; - : int list = [-1; 0; 1; 2; 3] # l1 @ [4; 5];; - : int list = [1; 2; 3; 4; 5]

Page 20: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

20

リストの分解

パターンマッチを使って行う

# let rec sum l = match l with [] -> 0 | hd :: tl -> hd + sum tl;; val sum : int list -> int = <fun> # sum [1; 2; 3; 4; 5];; - : int = 15

Page 21: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

21

今日の内容

パターンマッチ リスト型 Parametric Polymorphism ユーザ定義型

レコード型 バリアント型

多相データ型

Page 22: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

22

型多相の必要性

例: リストの先頭要素を得る関数 hd int_hd : int list -> int bool_hd : bool list -> bool string_hd : string list -> string intpair_hd : (int * int) list -> int * int …

操作は let hd (h::t) = h のように型によらず共通なのでまとめてしまいたい

型毎に異なる関数を作らなければならない

Page 23: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

23

型多相の必要性

解決法: 型をパラメタにしてしまう hd[α] : α list -> α

hd[int] : int list -> int hd[bool] : bool list -> bool hd[int * int] : (int * int) list -> int * int …

実際にはαをプログラマが明示する必要はない O'Caml の型推論が自動的に解決する

全部 hd[α] のインスタンスになっている

Page 24: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

24

Parametric Polymorphism

型をパラメタにすることで型は異なるが本質的に同一なモノをひとまとめにする方法 cf. オブジェクト指向の polymorphism

(≒ subtyping polymorphism) 例えば、Javaの継承

cf. overloading (ad-hoc polymorphism) 例えば、OCamlの=演算子

Page 25: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

25

多相関数の例

恒等関数

# let id x = x;; val id : 'a -> 'a = <fun> # id 1;; - : int = 1 # id [true; false];; - : bool list = [true; false] # id sum;; - : int list -> int = <fun>

型変数 α は'a で表される

任意の型の値に適用できる

Page 26: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

26

多相関数の例

ペアの要素を取り出す関数

# let fst (x, _) = x;; val fst : 'a * 'b -> 'a = <fun> # let snd (_, x) = x;; val snd : 'a * 'b -> 'b = <fun>

Page 27: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

27

多相関数の例

長さ n のリストを作る関数

# let rec mk_list n v = if n = 0 then [] else v :: mk_list (n – 1) v;; val mk_list : int -> 'a -> 'a list = <fun> # mk_list 3 1;; - : int list = [1; 1; 1] # mk_list 3 "1";; - : string list = ["1"; "1"; "1"]

Page 28: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

28

多相関数の例

反転させたリストを返す関数

# let rec rev l = let rec iter s d = match s with [] -> d | hd :: tl -> iter tl (hd :: d) in iter l [] val rev : 'a list -> 'a list = <fun> # rev [1; 2; 3];; - : int list = [3; 2; 1]

Page 29: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

29

多相関数の例

リストの各要素に関数を適用して返す関数

# let rec map f l = match l with [] -> [] | hd :: tl -> (f hd) :: (map f tl);; val map : ('a -> 'b) -> 'a list -> 'b list = <fun> # map fib [0; 1; 2; 3; 4];; - : int list = [1; 1; 2; 3; 5]

Page 30: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

30

型を明示的に指定する

多相型を持つ式, 変数に対し型を明示できる

# let f1 x = (x, x);; val f1 : 'a -> 'a * 'a = <fun> # let f2 (x : int) = (x, x);; val f2 : int -> int * int = <fun> # let f3 x = ((x, x) : int * int);; val f3 : int -> int * int = <fun> # f3 "string";; This expression has type string but...

Page 31: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

31

今日の内容

パターンマッチ リスト型 Parametric Polymorphism ユーザ定義型

レコード型 バリアント型

多相データ型

Page 32: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

32

独自データ型の定義

レコード (record) 複数の値を組にした値

C 言語の struct に相当

バリアント (variant) 何種類かの値のうち一つをとる値

C 言語の enum, union, cast などの組み合わせに相当

操作の安全性が型検査により完全に保証される

Page 33: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

33

レコード型

例: 複素数の直交座標表示

# type complex = { re : float; im : float };; type complex = { re : float; im : float };; # let c1 = { re = 5.0; im = 3.0 };; val c1 : complex = {re = 5.; im = 3.} # c1.re;; - : float = 5.

フィールドのラベル名で型を判別する

Page 34: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

34

レコード型

レコードに対するパターンマッチ

# let add_comp {re = r1; im = i1} {re = r2; im = i2} = {re = r1 +. r2; im = i1 +. i2};; val add_comp : complex -> complex -> complex = <fun> # add_comp c1 c1;; - : complex = {re = 10.; im = 6.}

Page 35: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

35

バリアント型

例: ノードに整数を持っている二分木

# type itree = Leaf | Node of int * itree * itree;; type itree = Leaf | Node of int * itree * itree # Leaf;; - : itree = Leaf # Node(1, Leaf, Leaf);; - : itree = Node(1, Leaf, Leaf)

大文字で始まる識別子はバリアント型のタグとみなされる

型の定義中にその型自身が用いられるような型を

再帰型と呼ぶ

Page 36: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

36

バリアント型

木のノードの値の合計を求める関数

# let rec sum_itree = function Leaf -> 0 | Node(a, t1, t2) -> a + sum_itree t1 + sum_itree t2;; val sum_itree : itree -> int = <fun> # sum_itree Node(4, Node(5, Leaf, Leaf), Leaf);; - : int = 9

Page 37: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

37

今日の内容

パターンマッチ リスト型 Parametric Polymorphism ユーザ定義型

レコード型 バリアント型

多相データ型

Page 38: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

38

多相データ型の必要性

二分木が持つ値は整数とは限らない itree = Leaf | Node of int * itree * itree btree = Leaf | Node of bool * btree * btree ibtree = Leaf

| Node of (int * bool) * ibtree * ibtree ...

データ構造としては同じなのでまとめたい 多相関数と同じような考え方ができないか?

Page 39: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

39

多相データ型の必要性

解決法: 再び 「型のパラメタ化」 α tree = Leaf | Node of α * α tree * α tree

int tree = Leaf | Node of int * int tree * int tree bool tree = Leaf | Node of bool * bool tree * bool tree ...

Page 40: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

40

多相データ型の例

ノードに要素を持つ二分木

# type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree;; type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree # Node(5, Leaf, Leaf);; - : int tree = Node(5, Leaf, Leaf) # Node("str", Leaf, Leaf);; - : string tree = Node("str", Leaf, Leaf)

Page 41: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

41

多相データ型の例

システム組み込みのバリアント型

'a option = None | Some of 'a 「存在しないかもしれない値」を表す型

'a list = [] | (::) of 'a * 'a list構文がちょっと特殊

Page 42: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

42

option 型の例

整数の割り算

# let div x y = if y = 0 then None else Some (x / y);; val div : int -> int -> int option = <fun> # div 4 3;; - : int option = Some 1 # div 4 0;; - : int option = None

Page 43: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

43

多相データ型と多相関数

木の深さを返す関数

# let rec depth = function Leaf -> 0 | Node(_, t1, t2) -> let d1 = depth t1 in let d2 = depth t2 in 1 + max d1 d2;; val depth : 'a tree -> int = <fun>

Page 44: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

44

2つ以上の型変数を含む多相データ型の定義

型の定義時に型変数をタプルの様に列挙する

# type ('a, 'b) pair = P of 'a * 'b;; type ('a, 'b) pair = P of 'a * 'b # P (42, "answer");; - : (int, string) pair = P (42, "answer")

Page 45: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

第2回 課題

締め切り: 6/26 13:00 (日本標準時)

Page 46: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

46

課題1 (必須)

以下の関数を定義せよ 引数の2リストを連結したリストを返す関数append: 'a list -> 'a list -> 'a list ただし@をつかってはいけない

判定関数とリストを受け取り元のリストの要素のうち条件を満たす要素だけからなるリストを生成する関数filter: ('a -> bool) -> 'a list -> 'a list# filter isprime [1; 2; 3; 4; 5; 6; 7; 8; 9];;

- : int list = [2; 3; 5; 7];;

Page 47: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

47

課題2 (必須)

2変数関数(⊕)と値 z とリスト [a1; a2;…; an ] を受け取り、右結合で結合させた結果 a1 ⊕ (a2 ⊕ (… ⊕ (an ⊕ z)…))を返す関数

foldr: ('a -> 'b -> 'b) -> 'b → 'a list → 'b

を定義せよ。

Page 48: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

48

課題2 (例)

# foldr (+) 0 [1; 2; 3; 4; 5];; - : int = 15 # let flatten x = foldr (@) [] x;; flatten : 'a list list -> 'a list # flatten [[1; 2]; [3; 4]; [5; 6; 7]];; - : int list = [1; 2; 3; 4; 5; 6; 7]

中置演算子は括弧で記号を囲むことで関数として使える 自分で定義することもできる

# let (%) x y = x mod y;; val ( % ) : int -> int -> int

# 5 % 3;;

- : int = 2

Page 49: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

49

課題3 (必須)

リスト lst と整数 n を受け取りlst から要素をn個取り出す組み合わせをリストにして返す関数

comb : 'a list -> int -> 'a list listを書け。

# comb [1; 2; 3] 2;;

- : int list list = [[1; 2]; [1; 3]; [2; 3]]

# comb [1; 2; 3] 0;;

- : int list list = [[]]

# comb [] 3;;

- : int list list = []

Page 50: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

50

課題4 (必須)

木 ('a tree) を受け取り以下に挙げた探索順で全要素を並べたリストを生成する関数 'a tree -> 'a list を定義せよ 行きがけ順 (preorder) 通りがけ順 (inorder) 帰りがけ順 (postorder)

Page 51: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

51

課題4 (例)

# preorder(Node(7, Node(5,Node(4,Leaf,Leaf),Leaf), Node(9,Leaf,Node(15,Leaf,Leaf))));;

- : int list = [7; 5; 4; 9; 15] 

7

5 9

4 15

Page 52: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

52

課題4 (例)

# inorder(Node(7, Node(5,Node(4,Leaf,Leaf),Leaf), Node(9,Leaf,Node(15,Leaf,Leaf))));;

- : int list = [4; 5; 7; 9; 15] 

7

5 9

4 15

Page 53: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

53

課題4 (例)

# postorder(Node(7, Node(5,Node(4,Leaf,Leaf),Leaf), Node(9,Leaf,Node(15,Leaf,Leaf))));;

- : int list = [4; 5; 15; 9; 7] 

7

5 9

4 15

Page 54: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

54

課題5 (Optional)

以下の条件を満たす2分探索木を実装してください 文字列を格納できること

入力方法は任意 格納される文字列の最大長を仮定してはいけない

削除機能を持つこと 格納されているデータをアルファベット順にソートして表示する機能を持つこと

もちろん木のノードを通りがけ順に読み出せば自動的にソートされているはずである

ファイルにセーブする機能を持つこと ファイルの構造は任意 内容のみでなく構造も保存すること

保存したファイルを読み込んで木を再構成する機能を持つこと

Page 55: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

55

課題6 (Optional)

型 bot と型 not と型 or_type が以下のように定義されているとする

type bot = B of bot type 'a not = 'a -> bot type ('a, 'b) or_type = L of 'a | R of 'b

このとき、次ページの1~6の型についてそれぞれの型を持つ値をlet rec や再帰型を用いずに定義できるか?

定義できる場合はその定義を示せ

let rec や再帰型を用いてよい場合はどうか?

Page 56: ML演習 第 - 東京大学sgotou/lecture/caml-enshu/...O'Caml の型推論が自動的に解決する 全部 hd[α] の インスタンスに なっている 24 Parametric Polymorphism

56

課題6 (Optional)

1. ('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)

2. ('a, 'a not) or_type

3. ('a, 'b * 'c) or_type

-> ('a, 'b) or_type * ('a, 'c) or_type

4. ('a, 'b) or_type * ('a, 'c) or_type

-> ('a, 'b * 'c) or_type

5. ('a * 'b) not

-> ('a not, 'b not) or_type

6. ('a not, 'b not) or_type

-> ('a * 'b) not