Programs written in, for example, Java rely a lot on dynamic dispatch.
How are such programs expressed in functional languages such as Haskell?
In other word
Maybe you need ADT plus pattern matching ?
data Animal = Dog {dogName :: String}
| Cat {catName :: String}
| Unicorn
say :: Animal -> String
say (Dog {dogName = name}) = "Woof Woof, my name is " ++ name
say (Cat {catName = name}) = "Meow meow, my name is " ++ name
say Unicorn = "Unicorns do not talk"