yield と collect イディオム
小町算、parse とか eval とかしないで解こうと思ったら、kinaba さんに elegant な解答をかかれたので萎えてやめた。
そういえば、yield って今まで存在すら知らなかったんですが、ここみてわかった。ずいぶん前に id:mmatsuoka さんのところで知った、collect イディオムの遅延バージョンですね!
let collect f = let acc = ref [] in let keep x = acc := x::!acc in f keep; List.rev !acc
collect では List の実体を作るが、yield では代わりに iterator を作るという寸法のようだ。こんなのできたのか、知らなかった。Python の iterator の文化は本当に見事だと思っていて、非常に統一されている。Python が好きな理由の一つはこの辺り。
yield では iterator を作りますが、代わりに1引数関数を適用させると捉えるのもおもしろい。List とは 関数 f を次々に適用させる関数のことだったんだよ!
let range n f = for i = 0 to n-1 do f i done ;; let lst = range 10 in lst print_int;; 0123456789 let map f lst g = lst (fun x -> g (f x)) ;; let lst2 = map (( * ) 2) lst in lst2 print_int;; 024681012141618
いや、まぁホントにどうでもいいんだけど。