3

関数従属性を使用して、Fooクラスを宣言できます。

class Foo a b c | a -> b where
    foo1 :: a -> b -> c
    foo2 :: a -> c

私が電話するとfoo2、すべてが正常に機能します。コンパイラは、依存関係があるため、使用するインスタンスを認識しています。

しかし、依存関係を削除して作成するとFoo'

class Foo' a b c where
    foo1' :: a -> b -> c
    foo2' :: a -> c

すべてが正常にコンパイルされますが、GHCを呼び出そうとすると、あいまいなfoo2'ために使用するインスタンスを解決できないというエラーがスローされます。b

foo2'エラーなしで電話をかけることは可能ですか?もしそうなら、どのように?そうでない場合、なぜコンパイルエラーが発生しないのですか?

4

1 に答える 1

3

foo2'Daniel Fischerが言うように、使用するインスタンスを決定する方法がないため、このコンテキストで呼び出すことは不可能です。たとえば、次の場合:

instance Foo' Int Int Int where
    foo2' x = x

instance Foo' Int Bool Int where
    foo2' x = x + 1

これらは両方ともfoo2'同じ型シグネチャを持っているため、どちらを呼び出すかを決定する方法はありません。

この問題を回避する通常の方法は、プロキシを使用することです。

data Proxy a = Proxy

class Foo'' a b c = where
    foo2'' :: Proxy b -> a -> c

どのインスタンスを選択するために、どのように使用しますか。

foo'' (Proxy :: Proxy Bool) 42
于 2013-01-05T01:52:21.313 に答える