How to make a heterogeneous list in Haskell? (originally in Java)

How to convert the following Java implementation to Haskell?

The main goal here is to have a list containing various elements that are a subtype of a particular interface.
I tried to make the version of Haskell lower, but could not complete my task. The point here xsis of type [Bar], notFoo a => [a]

Does this mean that Haskell cannot do this, and I will think differently?

Java

interface Foo {
    void bar ();
}

public class Bar1 implements Foo {
    @Override
    public void bar() {
        System.out.println("I am bar 1 class");
    }   
}

public class Bar2 implements Foo {
    @Override
    public void bar() {
        System.out.println("I am bar 2 class");
    }   
}

public static void main(String[] args) {
    // The major purpose here is having a list 
    // that contains elements which are sub-type of "Foo"
    List<Foo> ys = new ArrayList<Foo>();

    Foo e1 = new Bar1();
    Foo e2 = new Bar2();

    ys.add(e1);
    ys.add(e2);

    for (Foo foo : ys) {
        foo.bar();
    }
}

Haskell

class Foo a where
  bar :: a -> IO ()

data Bar = Bar1 | Bar2

instance Foo Bar where
  bar Bar1 = print "I am Bar1"
  bar Bar2 = print "I am Bar2"

--xs :: Foo a => [a]
xs :: [Bar]
xs = [Bar1, Bar2]

main :: IO ()
main = mapM_ bar xs
+4
source share
4 answers

: ! Haskell OO, , ADT.

List<Foo> Java Foo a => [a] Haskell: forall a . Foo a => [a]. a , , Foo .

Java: , , , Foo. Haskell , . , - , ! ... , , , , , 1 - bar. , ! IO() - , ( , ).

xs :: [IO ()]
xs = [bar Bar1, bar Bar2]


, , Haskell:
{-# LANGUAGE ExistentialQuantification #-}

data AFoo = forall a. Foo a => AFoo a

xs :: [AFoo]
xs = [AFoo Bar1, AFoo Bar2]

main = mapM_ (\(AFoo f) -> bar f) xs

: acknoledge, OO , Haskell. (, chunksOf 50, GADTs). Haskell , , , , " ...", OO, "" Haskell.


1 , , " " .. Java. Haskell Typeable . , .

+16

. Java Bar3, Foo, , Bar Haskell. , .

- . .

, . , Foo:

data Foo = Foo { bar :: IO () }

, Foo, [Foo].

+9

, , , . , " ", .

:

data Foo = Foo a

, "a" ADT. :

{-# LANGUAGE UnicodeSyntax, Rank2Types, GADTs, ConstraintKinds #-}

import Data.Constraint

-- List datatype:
data PList α where
   Nil  ∷ PList α
   (:*) ∷ α a ⇒ a → PList α → PList α

infixr 6 :*

-- Polymorphic map:
pmap ∷ (∀ a. α a ⇒ a → b) → PList α → [b]
pmap _ Nil      = []
pmap f (a :* t) = f a : pmap f t

main = let
        -- Declare list of arbitrary typed values with overloaded instance Show:
        l ∷ PList Show
        l = "Truly polymorphic list " :* 'a' :* 1 :* (2, 2) :* Nil
    in do
        -- Map show to list:
        print $ pmap show l

:

["\"Truly polymorphic list \"","'a'","1","(2,2)"]

, :

class Show a ⇒ Named a where
    name ∷ a → String

instance Named Int where
    name a = "I'm Int and my value is " ++ show a

instance Named Char where
    name a = "I'm Char and my value is " ++ show a

 main = let
        -- Declare list of arbitrary typed values with overloaded instance Named:
        l2 :: PList Named
        l2 = 'a' :* (1Int) :* Nil
    in do 
        print $ pmap name l2
        print $ pmap show l2

:

["I'm Char and my value is 'a'","I'm Int and my value is 1"]
["'a'","1"]
+7

All Articles