Concurrent Clean : Yコンビネータ

[id:desumasu:20060806:1154868741]を見て思い出した。
CleanでYコンビネータを書くとき、

y f = let g = f g in g

とか書いちゃうのだが、これは本来の意味から言っておかしい。
そこで、一般的なYコンビネータの定義

(define Y
  (lambda (f)
    ((lambda (proc)
       (f (lambda (arg) ((proc proc) arg))))
     (lambda (proc)
       (f (lambda (arg) ((proc proc) arg)))))))

を見習って、

y f = (\p = f (p p))
      (\p = f (p p))

とかと書くと、型エラーになってしまう。pに型を正しく付けられないのだ。
そこで、適当な型を用意してやって、

::P a = P ((P a) -> a)

y f = (\(P p) = f (p (P p)))
   (P (\(P p) = f (p (P p))))

としてやると、コンパイルが通る。
しかし、まあ、なんと言うか、ちょっとかっこ悪い。