F#

ふとF#とかいう言語があったなぁ、と思い出して、
どの程度実用になるんだろうかと試してみた。
.NETクラスとのやり取りをどうするかが問題になると思われるが、
なんか普通に使えてますね。ウインドウ出したりも出来るし。
何よりVisual Studioで使える。コード補完やデバッガが使えるのが大きい。


とりあえず何か作ってみようと思ったので、
なぜか、モナディックIOを実装してみた。全然F#である意味がないけど。
随分前にMLでもモナドでIOを扱うことは出来るが、意味がないのでやらない
とかいう記述をどこかで見たのだが、そのときは具体的にどうなるかが
分からなかったので、どうなるのかな、とやってみた。

(* IOモナドの定義 *)
type World = World of int
type 'a IO = IO of (World -> (World * 'a))

(* 演算子の定義 *)
let (>>=) (IO m1) f =
  let h w =
    let (w2,r) = m1 w in
    let (IO m2) = f r in
    m2 w2 in
  IO h

let (>>) (IO m1) (IO m2) =
  let h w =
    let (w2,_) = m1 w in
    m2 w2 in
  IO h

let Return a = IO (fun w -> (w,a))

(* IOモナドを実際に実行 *)
let run_io (IO f) = let _ = f (World 0) in ()

(* プリミティブな関数 *)
let put_str_ln (s:string) =
  let psl w = System.Console.WriteLine s ; (w,()) in
  IO psl

let get_line =
  let gl w =
    let s = System.Console.ReadLine () in
    (w,s) in
  IO gl

(* 使用例 *)
let hoge =
  get_line >>= fun s ->
  put_str_ln ("*** " ^ s ^ " ***")

(* IOモナドとの対比 *)
let hage () =
  let s = System.Console.ReadLine () in
  System.Console.WriteLine ("*** " ^ s ^ " ***")

let main = run_io hoge ; hage ()

Cleanに影響されてWorldを作ってみたが、要らなかったかもしれない。
使用例のほうは意外と自然かもしれない。
ただ、評価が遅延されないので、大きなプログラムを作ると
ものすごくでかいIOのデータが生成されるような気がする。
しかし、ひさしぶりにOcamlというかF#を触ったが、
見た目はHaskellとそれほど変わらないのに、
正格評価なので感覚がなんだかおかしくなった。
関数と変数が違うものだったり。
Haskellに慣れすぎているのかもしれない。