L'ajout de bdonlan réponse: au Lieu de GADTs, vous pouvez également utiliser existentielle types:
{-# LANGUAGE ExistentialQuantification #-}
class Foo a where
foo :: a -> a
data AnyFoo = forall a. Foo a => AnyFoo a
instance Foo AnyFoo where
foo (AnyFoo a) = AnyFoo $ foo a
mapFoo :: [AnyFoo] -> [AnyFoo]
mapFoo = map foo
C'est en gros équivalent à bdonlan de GADT solution, mais ne pas imposer le choix de la structure de données sur vous - vous pouvez utiliser un Map
au lieu d'une liste, par exemple:
import qualified Data.Map as M
mFoo :: M.Map String AnyFoo
mFoo = M.fromList [("a", AnyFoo SomeFoo), ("b", AnyFoo SomeBar)]
L' data AnyFoo = forall a. Foo a => AnyFoo a
bit peut également être écrit en GADT notation comme:
data AnyFoo where
AnyFoo :: Foo a => a -> AnyFoo