TrueCrypt
HDD丸ごと暗号化しちゃいます@@
boxing 機能を用いることで、「null値」と比較できます。box (value) <> nullパターンマッチで判断することもできます。match x.ReadLine() with | null -> None | line -> Some(line).NETライブラリで最終的に null値 を返す関数を扱うときの多相的関数(ジェネリック関数)#light /// Usage: "SeqGivenFuncTillNull<string>(sr.ReadLine)" let SeqGivenFuncTillNull<'a when 'a:not struct> (f:unit->'a) :seq<'a> = seq { let v = ref (f()) in while box (!v) <> null do yield !v do v := f() }StringReader を例にすると、以下のようになります。let str = "testeseテスト!\ndeoweiru!ewp!";; let sr = new StringReader(str);; let lineSeq = SeqGivenFuncTillNull<string>(sr.ReadLine);; let main = for line in lineSeq do printfn "%s" line doneStringReader は TextReader を継承しているので、 TextReader を拡張し、"SeqGivenFuncTillNull"を意識しないようにもできます。/// Extend IO.TextReader. type System.IO.TextReader with member it.to_string_seq = SeqGivenFuncTillNull<string>(it.ReadLine) // Usage: let s = "first line\nsecond line\nthird line\n" let sr2 = new System.IO.StringReader(s) for line in sr2.to_string_seq do // Life is good :) printfn "%s" line;;また、F#で扱いやすいように Option で包むことも可能です。type System.IO.TextReader with member x.TryReadLine() = match x.ReadLine() with | null -> None | line -> Some(line) let SeqGivenFuncTillNull2 (f:unit->'a option) :seq<'a> = seq { let v = ref (f()) while (!v) <> None do yield Option.get (!v) do v := f() }Labels: F# FSharp
Software Transactional Memory for F# http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx wikiによると、STMとは 「データベーストランザクションに似た並行性制御機構であり、並列計算を行う際の共有メモリへのアクセス法である。」 とある。 つまり、複数のスレッドから読み書きされるデータの整合性を保証する役目ってことかな。 従来のロックベースの代替案として注目を集めているみたい。 そんなわけで、リンク先にあるのは、「STMをF#で使えるようにしてみましたー!」的なライブラリ (コア部分はC#で書かれてるんだって) おまけとして「サンタクロース問題」のソース付Labels: F# FSharp
Memo : Node(左の木, このノードの値, 右の木)type 'a tree = Nil | Node of ('a tree) * 'a * ('a tree)再帰的: (通りがけ順, 中置記法)let rec map0 f t = match t with Nil -> Nil | Node(l,v,r) -> let v' = f v in Node(map0 f l, v', map0 f r)末尾再帰的: (帰りがけ順, 逆ポーランド記法)let map3 f tree = let rec map' subtree build = match subtree with | Nil -> build Nil | Node(l, v, r) -> let v' = f v in map' l (fun l' -> map' r (fun r' -> Node(l', v', r') |> build)) in map' tree (fun x -> x)テスト用コード:// 関数のリスト let maps : (string * (('a->'b) -> 'a tree -> 'b tree)) list = [ "map0 (non-tail-recursive):", map0; "map3 (Vladimir's functional):", map3; ] // 木の表示 let rec print_tree t = match t with Nil -> printf "" | Node(l,v,r) -> printf "("; print_tree l; printf "%d" v; print_tree r; printf ")" ;; // テスト用の木の用意と、関数のリストに登録されている関数の実行、そして木の表示 let _ = let tree = Node(Node(Node(Nil,1,Nil),2,Node(Nil,3,Nil)),5,Node(Node(Nil,6,Nil),7,Node(Nil,8,Nil))) in print_tree tree; printf "\n"; List.iter (fun (s,map) -> print_tree (map (fun x -> x+1) tree); printf "\n") maps ;;テスト用の木構造 結果:(((1)2(3))5((6)7(8))) -- テスト用の木 (((2)3(4))6((7)8(9))) -- 関数適用後の木 -- map0 (((2)3(4))6((7)8(9))) -- 関数適用後の木 -- map3再帰的な定義は、非常に簡潔でわかりやすく、実行速度も速い。しかし、メモリ消費量が大 末尾再帰的な定義は、簡潔ではなく、実行速度も遅い。しかし、メモリ消費量が小Labels: F# FSharp