2008-02-01から1ヶ月間の記事一覧

データの整列

どう書く?.orgに投稿した。cf. データの整列sort_by_dic が辞書順に整列する関数,sort_by_dis が距離の昇順に整列する関数。 type point = Point of float * float let compare_point a b = match (a, b) with (Point (x1, y1), Point (x2, y2)) -> if x1 …

データの整列(Haskell版)

同じことをHaskellで。Ordクラスのインスタンスにしたら sortByDic はただの sort ですんだ。 import List data Point = Pt Float Float deriving (Show, Eq, Ord) distance :: Point -> Float distance (Pt x y) = sqrt (x * x + y * y) sortByDic :: [Poin…

モジュールの定義

モジュール(正確にはストラクチャ)の定義は次のようにして,struct と endo のあいだに各種定義の書く。 # module Tree = struct type 'a t = Lf | Br of 'a * 'a t * 'a t let rec size = function Lf -> 0 | Br (_, left, right) -> 1 + size left + siz…

シグネチャ

前のエントリの例のようにシグネチャをコンパイラに推論させるのではなく,自分で書くこともできる。そのとき,モジュールの外部には公開したくない関数や,定義した型の詳細を隠蔽することもできる。一般には: シグネチャを定義する そのシグネチャをモジ…

シグネチャ(その2)

前エントリではモジュールの定義とシグネチャを与えるのを別にしたけど,いっぺんにすることもできる。というかその方が一般的なのかな。こんな感じ。 module Table1 : TABLE1 = struct ... end;;

open宣言

モジュールの関数を使うときには[モジュール名].[関数名]とするけど,open宣言をすればモジュール名をつけなくても使えるようになる。 # map (fun x -> x * x) [1;2;3;4];; Characters 0-3: map (fun x -> x * x) [1;2;3;4];; ^^^ Unbound value map # open …

FizzBuzz

出力も覚えたし書いてみた。 let fizzbuzz x = let f = if x mod 3 = 0 then "Fizz" else "" in let b = if x mod 5 = 0 then "Buzz" else "" in let fb = f ^ b in if fb = "" then string_of_int x else fb ;; let () = for i = 1 to 100 do print_endline…

練習問題8.6

本文中の関数 whle を参考にして,for式相当の機能を実現する再帰関数を定義しなさい。 こんなんでいいのかな。 # let rec fr frm t body = if frm <= t then begin body frm; fr (frm + 1) t body end ;; val fr : int -> int -> (int -> 'a) -> unit = <fun> # </fun>…

練習問題8.1

本文中でもふれたように,ref型は以下のように定義された,1フィールドの書き換え可能な レコードです。 type 'a ref = { mutable contents : 'a };; 関数 ref,前置演算子 !,中置演算子 := の定義をレコードに関連した操作で書きなさい。 こうかな。 let r…

練習問題8.2

与えられた参照の指す先の整数を1増やす関数 incr を定義しなさい。 # let incr x = x := !x + 1;; val incr : int ref -> unit = <fun> # let x = ref 3;; val x : int ref = {contents = 3} # incr x;; - : unit = () # !x;; - : int = 4</fun>

練習問題8.4

参照と繰り返しの構文(while,for)を使ってフィボナッチ数を求める関数を定義しなさい。 # let fib n = let fibs = ref (1, 1) in let i = ref 1 in while !i < n do fibs := (snd !fibs, fst !fibs + snd !fibs); i := !i + 1 done; snd !fibs ;; val fib…

チャネルを使った入出力

チャネルっていうのは,ファイルディスクリプタみたいなものだと思っておけば良さそう。 入力用には open_in と close_in を使う。 こういうファイル members.txt があったとして: ^o^ >type members.txt andy bill charlieファイルから入力する例。 # let i…

ファイルに追加出力する

open_out を使ってファイルを開くと,そのファイルがすでに存在した場合,中身を消去してしまう。既存のファイルに追加するには,open_out_gen を使ってチャネルを作る*1。 # let outfile = open_out_gen [Open_wronly; Open_append; Open_text] 0o666 "C:/h…

繰り返しのための高階関数

繰り返しの構造を関数(再帰関数)にすることもできる。 # let rec whle condition body = if condition () then begin body (); whle condition body end ;; val whle : (unit -> bool) -> (unit -> 'a) -> unit = <fun>condition () が真であるあいだ body を繰</fun>…

制御構造

入出力など,副作用のある計算をするときには式を評価する順番が重要になる。OCaml にもそのための制御構造(control structure)がある。 逐次実行 1つの方法は let 〜 in を使うこと。let 以下が評価された後に in 以下が評価される。 # let () = print_st…