【SML】高階関数と匿名関数

高階関数

  • 関数を引数とする関数
  • 関数を返す関数

その前に匿名関数について軽く触れておきます。

匿名関数

  • 名前をつけない関数。λx.M

匿名関数は以下のように使う

fn (<パラメータ>) => <式>

例えば、以下のように書けば、定義した関数をそのまま呼び出せる。

- (fn (x) => x * x) (2);

1回きりしか使わない関数であれば、名前つける必要もないし簡単に定義できる。

何回か使う場合には匿名関数を変数につっこんであげればいい。

- val square = fn (x) => x * x;
- square(2);

高階関数

例えば積分...

コンピュータで計算するための最もシンプルで直感的なアルゴリズム積分かな。

積分区間をn個に区切ってから全ての縦長いやつを足していくという方法。

δ ( f(a+(i-1)δ) + f(a+iδ) ) / 2

(* func.sml *)
fun trap (a, b, n, F) = 
        if n <= 0 orelse b-a <= 0.0 
                  then 0.0
    else
      let
        val delta = (b-a) / real(n)
      in
        delta * (F(a) + F(a+delta)) / 2.0 + trap(a+delta,b, n-1, F)
      end;
$ sml func.sml
[opening func.sml]
val trap = fn : real * real * int * (real -> real) -> real
- trap(0.0, 1.0, 10, fn(x)=>x*x); (* ここの10を大きくすると精度がよくなる *)

val it = 0.335 : real

simpleMapを書くとこんな感じ。

(* simpleMap *)
fun simpleMap (F, nil) = nil
  | simpleMap (F, x::xs) = F(x)::simpleMap(F, xs)
[opening simpleMap.sml]
val simpleMap = fn : ('a -> 'b) * 'a list -> 'b list (* 'がついてるものは型はなんでもいい!ただし同じ記号、例えばaは全て同じ型 *)
- simpleMap (fn (x) = x * 5, [1,2,3]);