Concurrent Clean と 多態性

[id:lethevert:20050906:p1]
昨日のポイントは、
リストは単一の型しか受け取ることができないことと、

    # f = foldl save f lst

のsaveが、型クラスで多重定義されているので、そのどれを使うのかがコンパイル時点で決められなければいけないということだと考えられます。
で、それでは、インターフェースのシグネチャリストをレコードに持ってしまえばいいのではないかと。そこで、存在量化変数を使うことができるのではないかと思って、やってみたのが下です。

module poly2

import StdEnv

Start
    # objlist = [castFileIO obj1, castFileIO obj2, castFileIO obj3, castFileIO obj4]
    = map save objlist
where
    obj1 = createObjectA 1 2
    obj2 = createObjectB "person" "peter"
    obj3 = createObjectB "company" "kaisya"
    obj4 = createObjectA 5 3


//**オブジェクト指向の矢型演算子
(-->) infixl 9 :: a (a -> b) -> b
(-->) a f = f a

//** 型クラス = インターフェース の定義 **/
class FileIO a
where
    save :: a -> String
IFileIO = E.a:
{ val :: a , save :: a -> String } castFileIO :: a -> IFileIO | FileIO a castFileIO x = { val = x , save = save } instance FileIO IFileIO where save {val, save} = save val //** オブジェクト ObjectA の定義 **/
ObjectA =
{ x :: Int , y :: Int } createObjectA x` y` = { x = x`, y = y` } instance FileIO ObjectA //型クラス FileIO の実装 where save obj = "(" +++ obj.x-->toString +++ ", " +++ obj.y-->toString +++ ")\n" //** オブジェクト ObjectB の定義 **/
ObjectB =
{ name :: String , value :: String } createObjectB n v = { name = n, value = v } instance FileIO ObjectB //型クラス FileIO の実装 where save obj = "name=" +++ obj.name +++ "\n" +++ "value=" +++ obj.value +++ "\n"

これは、正しく、多態的に動作することを確認しました。
しかし、

class FileIO a
where
    save :: *File a -> *File

とすると、uniqueness errorが起こります。

castFileIO :: a -> IFileIO | FileIO a
castFileIO x =
    { val = x
    , save = save
    }

なぜかはよく分かっていませんが、この部分が、一意性の問題に引っかかるようです。