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で。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…
前のエントリの例のようにシグネチャをコンパイラに推論させるのではなく,自分で書くこともできる。そのとき,モジュールの外部には公開したくない関数や,定義した型の詳細を隠蔽することもできる。一般には: シグネチャを定義する そのシグネチャをモジ…
前エントリではモジュールの定義とシグネチャを与えるのを別にしたけど,いっぺんにすることもできる。というかその方が一般的なのかな。こんな感じ。 module Table1 : TABLE1 = struct ... end;;
モジュールの関数を使うときには[モジュール名].[関数名]とするけど,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 …
出力も覚えたし書いてみた。 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…
本文中の関数 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>…
本文中でもふれたように,ref型は以下のように定義された,1フィールドの書き換え可能な レコードです。 type 'a ref = { mutable contents : 'a };; 関数 ref,前置演算子 !,中置演算子 := の定義をレコードに関連した操作で書きなさい。 こうかな。 let r…
与えられた参照の指す先の整数を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>
参照と繰り返しの構文(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…