ml 演習 第 2 回

75
ML 演演 演 2 演 演演演演 演演演演演 演演演演 、、 2011/04/19

Upload: binh

Post on 22-Feb-2016

74 views

Category:

Documents


0 download

DESCRIPTION

ML 演習 第 2 回. 新井淳也、中村宇佑、 前田俊行 2011/04/19. 今日の内容. 型多相性 Parametric Polymorphism ユーザ定義型 レコード型 バリアント型 多相データ型 例外 副作用を利用したプログラミング. Type Polymorphism. 型多相性. 型多相性とは ?. 異なる型を持つ値 ・式などを どうにかして まとめて扱う仕組みのこと. 型多相性が無いと悲惨な例 : リストの先頭を取出す関数. リストの要素の型によって 別々に定義しなければならなくなる - PowerPoint PPT Presentation

TRANSCRIPT

ML 2

ML 2 2011/04/19Parametric Polymorphism2Type Polymorphism?: val hd_int : int list -> int val hd_bool : bool list -> bool val hd_i_x_b : (int * bool) list -> int * booletc.let hd_int = function (x :: _) -> x ;; let hd_bool = function (x :: _) -> x ;;let hd_i_x_b = function (x :: _) -> x ;;

?

: hd[] : list

hd[int] : int list inthd[bool] : bool list boolhd[int * bool] : (int * bool) list (int * bool)OCaml hd[] Parametric PolymorphismCf. polymorphism ( subtyping polymorphism) JavaCf. overloading (ad-hoc polymorphism)OCaml Haskell type class8: # let id x = x;;val id : 'a -> 'a = # id 1;;- : int = 1# id [1; 2; 3];;- : int list = [1; 2; 3]# id (fun x -> x + 1);;- : int -> int = 'a 'b :# let fst (x, _) = x;;val fst : 'a * 'b -> 'a = # let snd (_, x) = x;;val snd : 'a * 'b -> 'b = 10: n # let rec make_list n v = if n = 0 then [] else v :: make_list (n 1) v;;val make_list : int -> 'a -> 'a list =

# make_list 3 1;;- : int list = [1; 1; 1]# make_list 4 "a";;- : string list = ["a"; "a"; "a"; "a"]11fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'afold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'bappend : 'a list -> 'a list -> 'a listfilter : ('a -> bool) -> 'a list -> 'a listsplit : ('a * 'b) list -> 'a list * 'b listcomb : 'a list -> int -> 'a list list# let id x = x;;val id : 'a -> 'a = # let id (x : int) = x;;val id : int -> int = # let id x = (x : int);;val id : int -> int = # id true;;This expression has type bool but13User-Defined Types (record)C struct (variant)C enum, union, struct

15:type = { 1 : 1; 2 : 2; }

: complex # type complex = { re : float; im : float };;type complex = { re : float; im : float };;16{ 1 = 1; 2 = 2; }

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

: # c1.re;;- : float = 5.18# let scalar n { re = r; im = i } = { re = n *. r; im = n *. i };;val scalar : float -> complex -> complex =

# scalar 2.0 { re = 5.0; im = 3.0 };;- : complex = {re = 10.; im = 6.}

match with type = 1 of 1 | 2 of 2 |

1: bool # type mybool = True | False;;type mybool = True | False2: # type value = Int of int | Bool of bool;;type value = Int of int | Bool of boolof

1: mybool # True;;- : mybool = True# False;;- : mybool = False2: # Int 156;;- : value = Int 156# Bool false;;- : value = Bool false

21:# let not = function | True -> False | False -> True;;val not : mybool -> mybool = # not True;;- : mybool = False# not False;;- : mybool = True# let print_value = function | Int i -> print_int i | Bool b -> print_string (if b then "true" else "false")val print_value : value -> unit = : inttree # type inttree = | Leaf | Node of int * inttree * inttree;;type inttree = Leaf | Node of int * inttree * inttreeinttree # Leaf;;- : inttree = Leaf# Node (1, Leaf, Leaf);;- : inttree = Node (1, Leaf, Leaf)| rec 23: # let rec sum_tree = function | Leaf -> 0 | Node (v, t1, t2) -> v + sum_tree t1 + sum_tree t2;;val sum_tree : inttree -> int = # sum_tree (Node(4, Node(5, Leaf, Leaf), Leaf));;-: int = 9: # type list = | Nil | Cons of int * list' and list' = | Nil' | Cons' of bool * list;;type list = Nil | Cons of int * list'and list' = Nil' | Cons' of bool * listand rec 25Polymorphic Data Typetype inttree = Leaf | Node of int * inttree * inttreetype booltree = Leaf | Node of bool * booltree * booltreetype ibtree = Leaf | Node of (int * bool) * ibtree * ibtree: tree[] = Leaf | Node of * tree[] * tree[]

tree[int] = Leaf | Node of int * tree[int] * tree[int]tree[bool] = Leaf | Node of bool * tree[bool] * tree[bool]: # 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 (true, Leaf, Leaf);;- : bool tree = Node (true, Leaf, Leaf)# Leaf;;- : 'a tree = Leaftype 'a option = None | Some of 'a

type 'a list = [] | (::) of 'a * 'a list# let div x y = if y = 0 then None else Some (x / y);;val div : int -> int -> int option = # div 8 2;;- : int option = Some 4# div 8 0;;- : int option = None# let rec height = function | Leaf -> 0 | Node (_, t1, t2) -> 1 + max (height t1) (height t2);;val height : 'a tree -> int = # type ('a, 'b) either = L of 'a | R of 'b;;type ('a, 'b) either = L of 'a | R of 'b# L 1;;- : (int, 'a) either = L 1Exceptions?0 etc.C++ Java 35?(* : raise () *)# let div_e x y = if y = 0 then raise Division_by_zero else x / y;;val div_e : int -> int -> int = # div_e 8 2;;- : int = 4# div_e 8 0;;Exception: Division_by_zero.?(* : try with 1 -> 1 | 2 -> 2 | *)# let div x y = try Some (div_e x y) with Division_by_zero -> None;;val div : int -> int -> int option = # div 8 2;;- : int option = Some 4# div 8 0;;- : int option = None:exception of

# exception My_exception;;exception My_exception

# My_exception;;- : exn = My_exception

# raise My_exception;;Exception: My_exception.

# exception My_int_exception of int;;exception My_int_exception of int# let isprime n = if n bool = ?# exception My_exception;;# exception My_int_exception of int;;# exception My_bool_exception of bool;;# let foo x = try bar x with | My_exception -> None | My_int_exception i -> Some i | My_bool_exception _ -> None;;with try with try try raise My_exception with My_int_exception i -> Some iwith My_exception -> None with with Programs with Side Effects?

Unit ()# ();;- : unit = ():

Unit # print_string;;- : string -> unit = # print_string "Foo\n";;Foo- : unit = ()

# read_line;;- : unit -> string = # let s = read_line ();;Barval s : string = "Bar" mutable # type bank_account = { name : string; mutable balance : int };;type bank_account = { name : string; mutable balance : int; } let old = match !r with None -> x | Some y -> y in r := Some x; oldOCaml Value restriction: OK: fun NG: let etc...# (fun () x -> x) ();;- : '_a -> '_a = 55Value restriction # let f = List.map (fun x -> (x, x));;(* *)val f : '_a list -> ('_a * '_a) list = : ()# let f xs = List.map (fun x -> (x, x)) xs;;val f : 'a list -> ('a * 'a) list = 56Value restriction Value restriction Andrew K. Wright, Matthias Felleisen.A Syntactic Approach to Type Soundness.Value restriction O'Caml Jacques Garrigue. Relaxing Value Restriction. OCaml 3.07 57 GoogleGoogle ScholarACM Digital Library ( http://www.acm.org/ )ACM CiteSeer.IST ( http://citeseerx.ist.psu.edu )Google Web 58 2 : 5/3 13:00 () 1 (5) ('a tree) (preorder) (inorder) (postorder)type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree 60 1 ()# preorder (Node(7, Node(5, Node(4, Leaf, Leaf), Leaf), Node(9, Leaf, Node(15, Leaf, Leaf))))- : int list = [7; 5; 4; 9; 15]75941561 1 ()# inorder (Node(7, Node(5, Node(4, Leaf, Leaf), Leaf), Node(9, Leaf, Node(15, Leaf, Leaf))))- : int list = [4; 5; 7; 9; 15]75941562 1 ()# postorder (Node(7, Node(5, Node(4, Leaf, Leaf), Leaf), Node(9, Leaf, Node(15, Leaf, Leaf))))- : int list = [4; 5; 15; 9; 7]75941563 2 (5)type 'a stack = { mutable s : 'a list }val new_stack : unit -> 'a stack(* stack *)val push : 'a stack -> 'a -> unit(* push *)val pop : 'a stack -> 'a(* pop stack Empty_stack *)64 2 ()# let s = new_stack ();;val s : '_a stack = {s = []}# push s 1;;- unit = ()# push s 2;;- unit = ()# pop s;;- : int = 2# pop s;;- : int = 1# pop s;;Exception : Empty_stack.65 3 (5) 2 let s = new_stack () val s : '_a stack = {s = []} 'a stack '_a stack '_a stack 'a stack 66 4 (10) O(1) type 'a queue = ???val new_queue : unit -> 'a queue(* queue *)val enqueue : 'a queue -> 'a -> unit(* *)val dequeue : 'a queue -> 'a(* queue Empty_queue *)67 5 (10) f f fix f fix f f (f (f (f (f (f (f ...))))))# let fib = fix (fun g n -> if n int = # fib 10;;- : int = 55 let rec 6 (10)Bool int E V (bool )V (int )E VE E + EE E - EE E * EE E / EE E && EE E || EE E = EE if E then E else E 6 () V valuetype value =| Bool_value of bool | Int_value of int E expr type expr = | Const of value | Add of expr * expr | 6 ()(if ((false = true) || (2 = 2)) && (3 = 5) then (3 + 5) 9 else 3 * (18 + 20)) + 42falsetrue22353593182042EqEqEqAddSubOrAndIfAddMulAdd 7 (15) 6 expr eval : expr -> valueBool int Eval_error 8 (20) false_t, not_t, and_t, or_t type false_t = B of false_ttype 'a not_t = 'a -> false_ttype ('a, 'b) and_t = 'a * 'btype ('a, 'b) or_t = L of 'a | R of 'b 17 let rec let rec ?73 8 ()('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)('a, ('b, 'c) and_t) or_t -> (('a, 'b) or_t, ('a, 'c) or_t) and_t(('a, 'b) or_t, ('a, 'c) or_t) and_t -> ('a, ('b, 'c) and_t) or_t('a, 'a not_t) or_t('a, 'a not_t) and_t'a -> 'a not_t not_t'a not_t not_t -> 'a74 9 (20) O(1) type 'a queue = ???val new_queue : unit -> 'a queue(* queue *)val enqueue : 'a queue -> 'a -> 'a queue(* *)val dequeue : 'a queue -> 'a * 'a queue (* queue Empty_queue *)75