YAMAGUCHI::weblog

噛み付き地蔵に憧れて、この神の世界にやってきました。マドンナみたいな男の子、コッペです。

Objective Caml 入門 手習い(5章)その3

まだ5章は続きます。

Exercise 4

問題

Exercise4 f, g を適当な型の関数とする. map f (map g l) を map を一度しか使用しない同じ意味の式 に書き換えよ.map (fun x -> ...) l の ... 部分は?

自分の答え
let f = string_of_float;;
let g = float_of_int;;
let ($) f g x = f (g x);;

let fun1 l = map f (map g l);;
let fun2 l = map (f $ g) l;;

let l = [1;2;3;4;5;6];;

print_list (fun1 l);;
print_list (fun2 l);;

Exercise 5

問題

Exercise5 forall, exists を fold_right, map を組み合わせて定義せよ

自分の答え
(* Exercise 5 *)
let rec forall_ p = function
  | [] -> true
  | x::rest -> if p x then forall_ p rest else false
;;

let rec exists_ p = function
  | [] -> false
  | x::rest -> (p x) or (exists_ p rest)
;;

let forall p l = List.fold_right (&&) (map p l) true;;
let exists p l = List.fold_right (||) (map p l) false;;

Printf.printf "%b\n" (forall (fun x -> x < 10) [1;2;3;4;5]);;
Printf.printf "%b\n" (forall (fun x -> x > 10) [1;2;3;4;5]);;
Printf.printf "%b\n" (exists (fun x -> x = 1) [1;2;3;4;5]);;
Printf.printf "%b\n" (exists (fun x -> x = 10) [1;2;3;4;5]);;

感想

この問題を解いて、「OCamlには関数を合成する演算子はないのかなあ?」と思ったのでした。あとExercise 6のforallのところでは&&を使って、existsではorを使ってるけど、andってないのかな?なんかコンパイラによってコンパイルできたりできなかったりするんだよなあ。

追記 2010.04.05

id:camlspotter より添削をいただきまして、とりあえず標準ライブラリを読めばなぜandとorがないのかがわかるとのこと。また関数合成演算子がないのはOCamlの65536不思議の一つとも。不思議多すぎ!