Ecco una classe molto utile:vincoli universalmente generalizzate
class Foo f a where
foo :: f a
E ti permette di fare mi ha valori di default per un sacco di tipi. In realtà, potrei anche non aver bisogno di sapere che cos'è a
.
instance Foo Maybe a where
foo = Nothing
ora ho un Maybe a
per tutti a
, e posso specializzarsi in un secondo momento.
specialize :: (forall a. f a) -> f Int
specialize x = x
fooMaybe :: Maybe Int
fooMaybe = specialize foo
Hmmm .... che fooMaybe
sembra abbastanza specifico. Vediamo se posso usare un contesto per generalizzarlo:
fooAll :: (Foo f a) => f Int
fooAll = specialize foo
Oops! Non indovinare.
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
Quindi, la mia domanda è, come posso scrivere fooAll
, la versione generalizzata di fooMaybe
? O, più in generale, come è possibile generalizzare universalmente un vincolo di typeclass?
Non è possibile. Bene, puoi scrivere 'fooAll' se crei un' esempio Foo f a dove foo = undefined'. Ma non è utile. Non è possibile quantificare universalmente il vincolo, non è possibile scrivere 'fooAll :: (forall a. Foo f a) => f Int'. –