OCamlでpa_monadを使わないでシンプルにモナドっぽく使う方法

すごいH本を読むとモナドが分かったような気になったので、OCamlでできないか試して見ました。

最初に調べるとOCamlではpa_monadを使ってHaskellのdo記法っぽい書き方をする方法があるのがわかった。

でも、p4でモジュールをリンクするのがたるいなーと思っていたらFunctorを使ってモナドを作る方法があるのも分かった。

ということで、なんとなく作ってたらリストモナドで虫食い算ができるようになったので記録しておきます。
参考にしたのは下のサイトのコード。これをpa_monadを使わないでやってみました。

自分が書いたソースは

module ListMonad = struct
  type 'a t = 'a list
  let bind lst f = List.concat (List.map f lst)
  let return x = [ x ]
  let ( >>= ) = bind
  let guard c =
    if c then return ()
    else []
end

let rec range a b =
  if a = b then []
  else a::range (a+1) b

let make =
  List.fold_left (fun x y -> x*10 + y) 0

let solve () =
  ListMonad.(
    range 1 10 >>= fun a ->
    range 0 10 >>= fun b ->
    range 0 10 >>= fun c ->
    range 0 10 >>= fun d ->
    range 0 10 >>= fun e ->
    let x = make [a;7;b;6;c] in
    let y = make [3;d;2;9;e;6] in
    guard (x * 7 = y) >>= fun _ ->
    return (x, y)
    )

https://bitbucket.org/toku/experiment/src/3efdb97202a77a452351de7be736e5e02dfeeaee/monad/monad.ml

Optionモナド(Maybeモナド)とListモナドがあればGoogleCodeJamとかICFPCで戦力になるんじゃないかと思う。

それと、OCamlのコード書くようになってF#のコードなら相当簡単に書けるようになったと実感した。
なんというかOCamlってC言語っぽいんだよね。必要十分の機能はある感じ。F#はそれに加えて.NETの豊富な機能を使えるのがいいと思う。

OCamlC言語に例えるのはアレかもしれないけど、標準ライブラリだけじゃどうやって仕事するんだって思うのでそう間違ってないはず。