2008-01-01から1年間の記事一覧

レコードのフィールド名は重ならないように

レコードの型を宣言するときの注意。既存の型と同じフィールド名を使ってしまうと,先に宣言した型のフィールド名が使えなくなってしまう。たとえば前エントリの student とその値が存在している状態で: # type student = {name : string; id : int};; type…

練習問題 5.2 (つづき)

5. 2つの[a1; ...; an] と [a1; ...; bn] を引数として,[(a1,b1); ...; (an,bn)] を返す関数 zip (与えられたリストの長さが異なる場合は長いリストの余った部分を捨ててよい)。 # let rec zip l1 l2 = match (l1, l2) with ([], _) -> [] | (_, []) -> […

練習問題 5.2

次の関数を定義しなさい。 1. 正の整数 n から 1 までの整数の降順リストを生成する関数 downto1。 # let rec downto1 n = if n = 0 then [] else n :: downto1 (n-1);; val downto1 : int -> int list = <fun> # downto1 6;; - : int list = [6; 5; 4; 3; 2; 1] </fun>…

クイックソート

Haskell で一番有名(?)なコードを OCaml で書いてみた。 # let rec qsort = function [] -> [] | hd::tl -> qsort (List.filter (fun x -> x < hd) tl) @ [hd] @ qsort (List.filter (fun y -> hd <= y) tl) ;; val qsort : 'a list -> 'a list = <fun> # qsor</fun>…

ガード付きマッチング節

パターンに条件を付加するのがガード。 # let abs' = function 0 -> 0 | n when n > 0 -> n | n -> (-1) * n ;; val abs' : int -> int = <fun>2番目の when n > 0 がガード。パターンは3番目と同じだけどここで条件分けをしている。3番目のパターンは条件が付い</fun>…

2つで引数にパターンマッチするには

タプルにしてしまえばいい。ただし,function構文はつかえない。 # let rec zip l r = match (l, r) with ([], _) -> [] | (_, []) -> [] | (h1::t1, h2::t2) -> (h1, h2) :: zip t1 t2 ;; val zip : 'a list -> 'b list -> ('a * 'b) list = <fun> # zip [1;2;3;</fun>…

function構文

match式によるパターンマッチを function構文で書くことができる。パターンマッチのための仮引数が現れないのがミソ。 # let rec sum_list = function [] -> 0 | hd::tl -> hd + sum_list tl ;; val sum_list : int list -> int = <fun> # sum_list [1;2;3;4;5;6;</fun>…

List.map

List.map はリストの各要素に関数を適用する。 # List.map (fun x -> x * x) [1;2;3;4;5];; - : int list = [1; 4; 9; 16; 25]実装してみる。 # let rec map' f l = match l with [] -> [] | hd::tl -> f hd :: map' f tl ;; val map' : ('a -> 'b) -> 'a li…

List.fold_left と List.fold_right

List.fold_left は左から,List.fold_right は右からたたみ込む。 # List.fold_left (fun x y -> "(" ^ x ^ "," ^ y ^ ")") "A" ["B";"C";"D"];; - : string = "(((A,B),C),D)" # List.fold_right (fun x y -> "(" ^ x ^ "," ^ y ^ ")") ["A";"B";"C"] "D";;…

リスト

あいだが開いてしまった。多相や型推論の部分はどうにも頭の整理できないので,先に進もう。リストは全体を [ と ] で囲って,要素を ; で区切る。[]は空リストを表す。 # [1;2;3];; - : int list = [1; 2; 3] # [];; - : 'a list = [] ||< ::(コンスオペレ…

match式とリストパターン

引数のパターンマッチには match式をつかう。リストパターンは :: を使える。たとえば: # let rec sum l = match l with [] -> 0 | hd::tl -> hd + sum tl ;; val sum : int list -> int = <fun> # sum [1;3;5;7;9];; - : int = 25</fun>

List.length

List.length はリストの長さを返す。 # List.length [1;2;3;4;5];; - : int = 5実装してみる。 # List.length [1;2;3;4;5];; - : int = 5 # let rec length' l = match l with [] -> 0 | hd :: tl -> 1 + length' tl ;; val length' : 'a list -> int = <fun> # l</fun>…

List.append

List.append は2つのリストを連結する。 # List.append [1;2;3] [4;5;6];; - : int list = [1; 2; 3; 4; 5; 6]実装してみる。 # let rec append' l1 l2 = match l1 with [] -> l2 | hd::tl -> hd :: append' tl l2 ;; val append' : 'a list -> 'a list -> '…

reverse

reverse はリストを逆順にする。 # let rec reverse l = match l with [] -> [] | hd::tl -> (reverse tl) @ [hd] ;; val reverse : 'a list -> 'a list = <fun> # reverse [1;2;3;4;5];; - : int list = [5; 4; 3; 2; 1]</fun>