[Haskell-cafe] Re: Functional version of this OO snippet
Apfelmus, Heinrich
apfelmus at quantentunnel.de
Fri Dec 5 10:20:24 EST 2008
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
More information about the Haskell-Cafe
mailing list