I want to apply a function to every element in a list (map) but the elements may have different types but all implement the same function (here "putOut") like an interface. However I cannot create a list of this "interface" type (here "Outputable").

How do I map a list of different types implementing the same function?

```
import Control.Monad
main :: IO ()
main = do
mapM_ putOut lst
where
lst :: [Outputable] -- ERROR: Class "Outputable" used as a type
lst = [(Out1 1),(Out2 1 2)]
class Outputable a where
putOut :: a -> IO ()
-- user defined:
data Out1 = Out1 Int deriving (Show)
data Out2 = Out2 Int Int deriving (Show)
instance Outputable Out1 where
putOut out1 = putStrLn $ show out1
instance Outputable Out2 where
putOut out2 = putStrLn $ show out2
```

Haskell doesn't allow for heterogenous lists. So you cannot make a list of Outputables, because your `Out1`

and `Out2`

are two distinct types, even if they both belong to the same type class.

But there is a workaround which allows to simulate heterogeneous lists with `ExistentialQuantification`

. See an example of heterogeneous lists in Haskell wikibook.

### How to use

Put

`{-# LANGUAGE ExistentialQuantification #-}`

at the top of the moduleDefine a box type, which hides heterogeneous elements inside:

`data ShowBox = forall s. Show s => SB s heteroList :: [ShowBox] heteroList = [SB (), SB 5, SB True]`

Define a necessary class instance for the box type itself:

`instance Show ShowBox where show (SB s) = show s`

Use a list of boxes.

### An example

Your example may be rewritten as:

```
{-# LANGUAGE ExistentialQuantification #-}
main :: IO ()
main = do
mapM_ print lst
putStrLn "end"
where
lst :: [Printable]
lst = [P (Out1 1),P (Out2 1 2)]
-- box type (2)
data Printable = forall a . Show a => P a
-- necessary Show instance for the box type (3)
instance Show Printable where show (P x) = show x
-- user defined:
data Out1 = Out1 Int deriving (Show)
data Out2 = Out2 Int Int deriving (Show)
```