
Thomas Davie wrote:
Andrew Wagner wrote:
Hi all, public interface IEngine { void foo(); void bar(string bah); ... } public class Program { public void Run(IEngine engine){ while(true){ string command = GetLine(); if (command.startsWith("foo")){ engine.foo(); } else if (command.startsWith("bar")){ engine.bar(command); ... else break; }
In other words, I want to provide the same UI across multiple implementations of the engine that actually processes the commands.
class IEngine a where foo :: a -> String bar :: a -> String -> String
You don't even need a type class, a simple data type is enough. data Engine = Engine { foo :: IO (), bar :: String -> IO () } run e = processCommand e =<< getLine processCommand e c | "foo" `isPrefixOf` c = foo e >> run e | "bar" `isPrefixOf` c = bar e c >> run e | otherwise = return () This always works because all object methods expect a "self" argument. In other words, all type class translations of OOP classes have the form class IFoo a where method1 :: a -> ... method2 :: a -> ... ... See also http://www.haskell.org/haskellwiki/Existential_type#Using_constructors_and_c... Regards, H. Apfelmus