Note that you can already iterate over a list in two ways:
ghci> let hetlist = (1 :: Int) :*: ("two" :: String) :*: (3.0 :: Double) :*: ()
ghci> hetlist
((1 :*: "two") :*: 3.0) :*: ()
ghci> hetlist == hetlist
True
You can imitate this using your own classes:
class DoStuff a where
dostuff :: a -> a
instance DoStuff Int where dostuff i = 2*i
instance DoStuff String where dostuff s = s ++ s
instance DoStuff Double where dostuff d = d / 2
instance DoStuff () where dostuff () = ()
instance (DoStuff a, DoStuff b) => DoStuff (a :*: b) where
dostuff (a :*: b) = dostuff a :*: dostuff b
And then iterating over the collection happens automatically
ghci> dostuff hetlist
((2 :*: "twotwo") :*: 1.5) :*: ()
Alternatively, you can do the same using ExistentialQuantificationwrapper types, and then you will not need to define your own list type.
data DoStuffWrapper = forall a. (DoStuff a) => DoStuffWrapper a
homlist = [ DoStuffWrapper (1 :: Int)
, DoStuffWrapper ("two" :: String)
, DoStuffWrapper (3.0 :: Double)
]
homlist' = map (\(DoStuffWrapper a) -> DoStuffWrapper (dostuff a)) homlist
source
share