Adding to bdonlan's answer: Instead of GADTs, you can also use existential 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
This is basically equivalent to bdonlan's GADT solution, but doesn't impose the choice of data structure on you - you can use a Map
instead of a list, for example:
import qualified Data.Map as M
mFoo :: M.Map String AnyFoo
mFoo = M.fromList [("a", AnyFoo SomeFoo), ("b", AnyFoo SomeBar)]
The data AnyFoo = forall a. Foo a => AnyFoo a
bit can also be written in GADT notation as:
data AnyFoo where
AnyFoo :: Foo a => a -> AnyFoo
name
to have really any type, you should use a type variable. But: are you sure, that thename
of a person should have any type? Probably (for instance) anInt
-value as aname
or aBool
-value as a name is not sound!? – phynfo