Concurrent Clean の型付け

Cleanでちょっと複雑なプログラムを書いていて気づいたのだけれど、型に対する扱いが、CやJavaDelphiなどとは違うことを改めて感じた。いや、以前から知識としては知っていたのだけれど、実際にコードを書いて、コンパイラから文句を言われると、初めは戸惑う。
Cleanでも、型を記述することはできるのだけれど、コンパイラは、記述した型を全く参考にせず、すべて型推論で型を決定しているのです。ソースコードに書かれた型は、ただプログラマの意図と合っているかどうかをチェックするためと、注釈などを追加するためだけに使われているのです。
これは、レコード型を使っていると、顕著に感じられることで、以下のようなコードは、コンパイルが通らない。

RecordA =
{ x :: Int , y :: String }
RecordB =
{ x :: Int , z :: Int } addToRecordA :: Int RecordA -> Int addToRecordA i {x} = i + x

「x」の型が、型推論で判断できないためで、型推論を補助するために、下のように書く必要がある。

addToRecord i {RecordA | x}
    = i + x

あるいは、このように書く。

addToRecord i obj
    = i + obj.RecordA.x