SICP : Ex1.44 : Java

[id:lethevert:20060126:p1]
関数を平準化するSmooth関数を作る問題。
Javaでカリー化を前提とした高階関数が書けるということを確認するという問題でもある。
[id:lethevert:20060127:p3]で作ったIterクラスを総称化したクラスに対して、Smoothクラスを適用して、N階Smoothクラス(nthFoldSmooth)を自動生成します。
さすがにConcurrent Cleanのコードと比べると冗長ですが、トリッキーなコードではないです。

abstract class Iter<A> {
  int n = 1;
  abstract A f(A i);

  Iter(int n) { this.n = n;}
  A $(A i) {
    for (int c=0; c<n; ++c){ i = f(i);}
    return i;
  }
}

abstract class Smooth {
  abstract double f(double x);
  double dx = 0.1; //テスト用
  double $(double x) {
    return (f(x-dx) + f(x) + f(x+dx))/3.0;
  }
}

public class Main {
  public static void main(String[] args) {
    Iter<Smooth> nthFoldSmooth = new Iter<Smooth>(10) {
      Smooth f(final Smooth s) {
        return new Smooth() {
            double f(double x) { return s.$(x);}
          };
      }
    };
    Smooth smooth = new Smooth() {
        double f(double x) { return (-dx/2.0 < x && x < dx/2.0)?1.0:0.0;}
      };

    for (int i=-10; i<=10; ++i) {
      final double j = i/10.0;
      System.out.println(j + " -> " + nthFoldSmooth.$(smooth).f(j));
      // 注)最後を"$"にすると、Clean版より関数適用が一回多くなる。
    }
  }
}