On May 28, 2013, at 12:36 AM, harry <voldermort@hotmail.com> wrote:
Every OO language which supports generics allows a declaration such as List<Show> alist, where Show is an interface. Any type implementing Show can be put in alist, and any Show operation can be performed on the alist's members. No casts, wrappers, or other special types and plumbing are needed.
Why isn't it possible to do this directly in Haskell?
My impression is that you often don't have this requirement, since functions are first-class values and you can treat them as closures. Consider this (silly) C++: struct Iface { // Yields the length of the printable representation of some object, plus some custom value. virtual int lengthPlus( int i ) = 0; }; struct MyString : Iface { MyString( const std::string &s ) : m_s( s ) { } virtual int lengthPlus( int i ) { return m_s.size() + i; } std::string m_s; }; struct MyBoolean : Iface { MyBoolean( bool b ) : m_b( b ) { } virtual int lengthPlus( int i ) { return m_b ? strlen( "True" ) + i : strlen( "False" ) + i; } bool m_b; }; You could now have code like: std::list<Iface *> l; l.push_back( new MyString( "Sample" ) ); l.push_back( new MyBoolean( true ) ); std::list<Iface *>::const_iterator it, end = l.end(); for ( it = l.begin(); it != end; ++it ) { std::cout << (*it)->lengthPlus( 4 ); } Now, in Haskell you wouldn't need the interface in the first place. You could use plain functions (I'm using slightly ugly naming here to show the parallels to the C++ code): MyString_lengthPlus :: String -> Int -> Int MyString_lengthPlus s i = length s + i MyBoolean_lengthPlus :: Bool -> Int -> Int MyBoolean_lengthPlus True i = 4 + i MyBoolean_lengthPlus False i = 5 + i l :: [Int -> Int] l = [MyString_lengthPlus "Sample", MyBoolean True] print $ map ($ 4) l Note how, just like in C++, the type of the actual value on which the 'map' in the last line works on is hidden at the moment the list 'l' is populated with values. -- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing