わんくまでF#に敬意を表しつつセッション発表してきました、というお話
用意するモノ
- F#に対する敬意
- タキシード
- やけくそな気持ち
用意しないモノ
- 平常心
F#で関数型言語に触れてみよう
タキシード着てF#のコーディングする人間がいても別に驚かないけど、
まさか自分がそうなるとは思ってませんでした。
F#で関数型言語に触れてみよう
View more presentations from wof moriguchi.
発表中に作った(コピペした)コードがこちらです。
let verboseLevel = ref 0 let warningLevel = ref 0 let isQuiet = ref false let outputfile = ref "default.out" let parse_args args = let specs = [ ("-v", "--Verbose", None, Some(fun x -> verboseLevel := Int32.Parse(x)) ); ("-w", "--Warn", None, Some(fun x -> warningLevel := Int32.Parse(x)) ); ("-q", "--Quiet", Some(fun _ -> isQuiet := true), None ); ("-o", "--Output", None, Some(fun x -> outputfile := x) ); ] let rec parse files xs = match xs with | [] -> files | hd :: tl -> let a = List.tryFind (fun (shop, op, _, _) -> shop = hd || op = hd) specs match a with | Some (_, _, Some(f), None) -> f (); parse files tl | Some (_, _, None, Some(f)) -> f tl.Head; parse files tl.Tail | Some (_, _, _, _) -> failwith "oops!" | None -> parse (files @ [hd]) tl Array.toList args |> List.tail |> parse []
そんで、このコードを見て[twitter:@mzp]さんが、「このコードはアカン!粛正リファクタリングしる!」と!ライトニングトークで粛正リファクタリングしていただいたのがこちらです。
let verboseLevel = ref 0 let warningLevel = ref 0 let isQuiet = ref false let outputfile = ref "default.out" type act = Noarg of (unit -> unit) | Onearg of (string -> unit) let parse_args args = let specs = [ ("--Verbose", "-v", Onearg(fun x -> verboseLevel := Int32.Parse(x))); ( "--Warn","-w", Onearg(fun x -> warningLevel := Int32.Parse(x))); ("--Quiet", "-q", Noarg(fun _ -> isQuiet := true)); ("--Output", "-o", Onearg(fun x -> outputfile := x)); ] let rec parse files = function | [] -> files | hd :: tl -> let a = List.tryFind (fun (op, shop, _) -> hd = op || hd = shop) specs match a with | Some (_, _, Noarg(f)) -> f (); parse files tl | Some (_, _, Onearg(f)) -> f tl.Head; parse files tl.Tail | None -> parse (files @ [hd]) tl args |> Array.toList |> List.tail |> parse []
判別共用体を使うアイデアは思いつきませんでした。こっちの方がスッキリしますね。
個人的には面白かったです。