Concurrent Clean : フィボナッチ数列

[id:lethevert:20060531:p5]につっこみ(http://www.jmuk.org/d/?path=2006/05/31)がついていました。
なぜ、

fib = [0,1:zipWith (+) fib (tl fib)]

と書かないのか、という指摘。
これは、ややバッドノウハウですが、Cleanの言語仕様で、大域定義と局所定義の解釈が違うことに起因しています。*1
大域定義では、普通に「=」を使って定義すると、常に関数として解釈されます。そのため、上の定義は、再帰的にfib関数を呼び出す関数定義として解釈されます。これは、普通に「fib n = if (n < 2) n (fib (n-1) + fib (n-2))」という定義をするよりもはるかに効率が悪くなります。
それに対し、局所定義では、引数も型指定もない場合には、関数ではなく定グラフであると解釈されます。定グラフであれば、狙い通りに遅延評価が効いて、効率のよい計算が行われます。
ですから、局所定義を作るために、letを導入しただけなので、次のようにStart関数の局所定義としてfibを定義する方が見た目的にはすっきりするかもしれません。

Start = fib
  where
    fib = [0,1:zipWith (+) fib (tl fib)]

逆に、Haskellでは、定関数と定グラフの区別って、どうつけているのでしょう?

*1:Clean入門でも「Clean入門(18):定グラフ」で扱っています。