F# はじめました

.Net が使える ocaml として有名な F# をちょっと触っています。
全然 ocaml と違いました。

とりあえずハローワールド

[<EnryPoint>]
let main _ = printfn "Hello, world!";;

エントリーポイント属性必要とかモジュールの最後の関数じゃないとダメとか面倒くさい。

あなごるの問題やろうかなーと思ったけどあなごるに F# ない…とりあえずフィズバズ。

let (|Num|Fizz|Buzz|FizzBuzz|) n =
  match (n % 3, n % 5) with
    | (0, 0) -> FizzBuzz
    | (0, _) -> Fizz
    | (_, 0) -> Buzz
    | _ -> Num n

let to_fizzbuzz = function
  | Num n -> string n
  | Fizz -> "Fizz"
  | Buzz -> "Buzz"
  | FizzBuzz -> "FizzBuzz"

[<EntryPoint>]
let main _ =
  [1..100] |> List.map to_fizzbuzz |> String.concat "\n" |> printfn "%s"; 0

無駄に active pattern 使ってみた。完全に無駄。

ocaml といえば module です。(F# は ocaml ではありません)

module M = struct let add = (+) 1 end

ocaml が struct ... end だから struct 使えますが F# では begin ... end が正しいらしい。

module M = begin let add = (+) 1 end

インデントがちゃんとあっていれば begin ... end は省略できます。

module M =
  let add = (+) 1

begin ... end に限らず色々省略できます。

let f =
  let g = (+)
  g 1.0

ocaml に慣れているとちょっとギョッとしますね…
あと、さりげなく (+) が float -> float -> float として使われていますが、これも ocaml と比べると少しびっくりです。別に nominal subtyping が行われているわけではないので、Num a => a -> a -> a とかではないです。実際にはオーバーロードが行われていて、単に (+) とかすると int -> int -> int になります。不思議〜。

モジュールに戻ります。



ここまで書かれた状態で下書き保存していたんですが続き書く気持ちがなくなったのでここで公開です…モジュールの扱いが全然違うよーっていう話が書きたかったのに…