2013-05-09 12 views
5

ここではかなり有用なクラスです:ユニバーサル・一般制約

class Foo f a where 
    foo :: f a 

それは私のタイプの多くのデフォルト値を作成してみましょう。実際には、aが何であるかを知る必要はないかもしれません。

instance Foo Maybe a where 
    foo = Nothing 

は今、私はすべてのaためMaybe aを持っている、と私は後でそれを特化することができます。

specialize :: (forall a. f a) -> f Int 
specialize x = x 

fooMaybe :: Maybe Int 
fooMaybe = specialize foo 

Hmmm ....そのfooMaybe確かにかなり特殊なようです。コンテキストを使って一般化することができるかどうかを見てみましょう:

fooAll :: (Foo f a) => f Int 
fooAll = specialize foo 

おっと!ないと思います。

Foo.hs:18:21: 
    Could not deduce (Foo * f a1) arising from a use of `foo' 
    from the context (Foo * f a) 
     bound by the type signature for fooAll :: Foo * f a => f Int 
     at Foo.hs:17:11-28 

だから、私の質問は、どのように私は、fooMaybeの一般化バージョンをfooAll書くことができますか?または、より一般的には、一般的なtypeclass制約を普遍化できますか?

+1

あなたはできません。さて、 'インスタンスFoo f a where foo = undefined'を作ると、' fooAll'を書くことができます。しかし、それは有用ではありません。普遍的に制約を定量化することはできません。fooAll ::(forall a .Foo f a)=> f Int'を書くことはできません。 –

答えて

7

現行のHaskellでは良い方法ではありません。 constraintsパッケージでは、do what you needのようなタイプがありますが、最近私はそれをどのように破壊するかを考え出しました。おそらくあなたの最良の賭け。誰かがそれを正しく行う方法を見つけたら、おそらく更新されます。

fooAll :: Forall (Foo f) => f Int 
fooAll = specialize foo_f where 
    foo_f :: forall a. f a 
    foo_f = foo \\ (inst `trans` (Sub Dict) ::() :- Foo f a) 
関連する問題