主にSparkleのソースを読むときに、型の表記がよくわからんのがキモイということで調べた。他はまあ、Haskell分かれば、(書けるかどうかは知らんが)とりあえず、読めるかな〜と
・基本型
Int,Bool,Char,Real

・一意型
型の前に、*を付けると一意型。一意型はよーわからんが、線形型に於けるexponentialの逆みたいなもん。一意型の変数は一回しか使えないらしい

・属性変数
id:: u:a -> u:aみたいなやつ。よく分からんが、idの引数の型が一意型(つまり、*a)の場合は、返り値も一意型*aで、非一意型(普通の型)aの場合は、返り値も、非一意型aだというのを表すのに使うらしい。idの場合は、別に、引数の型と返り値の型は一緒なので、id:a->aでいい気もするけどダメなのかな。hoge:: u:pnya -> u:pnyiみたいなケースだと、こういうのないと困るよね〜と

・無名属性変数
名前の通り。u:aと書く代わりに、型の前にドットを付けた.aとかいうやつ。可読性をあげるとか書いてあるが、却ってややこしい気が

・正格性注釈
!を付けると、その引数について、正格に評価するようにコンパイラに指示できるらしい。Libraries/StdEnv/StdList.iclより例

hd::![.a] -> .a
hd [a:x]	= a
hd []		= abort "hd of []"

・型クラス
Libraries/StdEnv/StdList.iclより例

sum:: !.[a] -> a |  + , zero  a
sum xs = accsum xs zero
where
	accsum [x:xs] n = accsum xs (n + x)
	accsum []     n = n

zeroと+は型クラス名で、型aがこの二つの型クラスのinstanceであるという制約を表している。Haskell風に書くと、"sum::(+ a , zero a)=>!.[a]->a"みたいな感じかな。


参考にしたサイト
http://www.geocities.jp/lethevert/clean/gettingStarted15.html
http://sky.zero.ad.jp/~zaa54437/programming/clean/LanguageReport21/Chap9.html#sc1
http://www.geocities.jp/lethevert/clean/gettingStarted12.html


http://d.hatena.ne.jp/m-a-o/20070106#p3で、sumはstrictness analysis外しても問題なく動くな〜って書いたけど、正格性注釈のおかげっぽい。にしても、一意型とか属性変数とかが、複雑に絡んでくると、頭が混乱するんだけど、これは慣れなのか

まとめ:CleanのコードをHaskellに移植するときは、型クラス以外はどうでもいい