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_combinators Regards, H. Apfelmus _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe