Caveat; after some reading it appears dynamic dispatch happens at runtime, a lot of haskell stuff is figured out at compile so I'm not sure this is entirely accurate. The idea is, not sure about the name.
First some Java showing dynamic dispatch:
// You have an interface
public interface Comparator<T> {
int compare(T o1, T o2); // virtual (per default)
}
// You implement it
public class MyComparator implements Comparator<String> {
private final int _n;
MyComparator(int n) {
_n = n;
}
int compare(String s1, String s2) {
return s1.charAt(_n) - s2.charAt(_n);
}
}
// Now you can use it
Collections.sort(myList, new MyComparator(5));
// Just use higher order functions
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
myComparator :: Int -> (String -> String -> Ordering)
myComparator n = \s1 s2 -> (s1 !! n) `compare` (s2 !! n)
-- n is implicitly stored in the closure of the function we return
foo = sortBy (myComparator 5) myList
public void <T> sortBy(List<T> list, Ordering FUNCTION(T, T) comparator) { ... }
public (Ordering FUNCTION(String, String)) myComparator(int n) {
return FUNCTION(String s1, String s2) {
return s1[n].compare(s2[n]);
}
}
public void foo() {
sortBy(myList, myComparator(5));
}
public class Widget {
public void onMouseClick(int x, int y) { }
public void onKeyPress(Key key) { }
public void paint() { }
...
}
public class MyWidget extends Widget {
private Foo _foo;
private Bar _bar;
MyWidget(...) {
_foo = something;
_bar = something;
}
public void onMouseClick(int x, int y) {
...do stuff with _foo and _bar...
}
}
Store info in closures, not an extra type:
data Widget = Widget {
onMouseClick :: Int -> Int -> IO (),
onKeyPress :: Key -> IO (),
paint :: IO (),
...
}
constructMyWidget :: ... -> IO Widget
constructMyWidget = do
foo <- newIORef someFoo
bar <- newIORef someBar
return $ Widget {
onMouseClick = \x y -> do
... do stuff with foo and bar ...,
onKeyPress = \key -> do ...,
paint = do ...
}