2013-05-09 71 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 

嗯.... 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 

所以,我的問題是,我怎麼能寫fooAllfooMaybe廣義的版本?或者更一般地說,我該如何普遍推廣一個類型類約束條件

+1

你不能。那麼,如果你創建了'Foo f a where foo = undefined',你可以寫'fooAll'。但這沒有用。你不能普遍量化約束,你不能寫'fooAll ::(forall a。Foo f a)=> f Int'。 – 2013-05-09 10:15:27

回答

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)