Hi Folks,<br><br>I am redesigning a system previously implemented in C++ using Haskell. I am keen to adopt a native programming style, but certain things about the original implementation still make perfect sense to me, including the C++-style subtype polymorphism. I&#39;d be grateful if someone could take a look at the following sample and tell me if I&#39;m missing some neater possible implementation in Haskell.<br>

<br><span style="font-family: courier new,monospace;">{-# OPTIONS -fglasgow-exts #-}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- for existential types</span><br style="font-family: courier new,monospace;">

<br><span style="font-family: courier new,monospace;">-- all subclasses take the same input format and can be created factory-pattern style</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">data Input = Input Int Int<br></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- this is the class we have to implement when creating a &#39;subtype&#39;</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">class InternalAPI i where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    doitImpl :: i -&gt; Input -&gt; Int</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    -- factory function, everything is initialised by giving an &quot;i&quot; and the Input</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    create :: i -&gt; Input -&gt; PublicAPI</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    create a b = PublicAPI a b<br style="font-family: courier new,monospace;">

</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- this is the object clients see, regardless of the underlying implementation</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">data PublicAPI = forall p. InternalAPI p =&gt; PublicAPI p Input</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">doit (PublicAPI p i) = doitImpl p i</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- Here&#39;s an example implementation of something trivial</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">data Adder = Adder</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">instance InternalAPI Adder where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    doitImpl _ (Input a b) = a + b  -- first argument is superfluous</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- There&#39;s the factory function in use:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">test = create Adder (Input 1 2)</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">result = doit test</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">I&#39;m actually pretty happy with this. I&#39;m not trying for a complete OOP implementation but it lets me:<br>

- have the &#39;base class&#39; (InternalAPI) implement default versions of methods with full access to the &#39;Input&#39; structure containing the member data<br>- do further inheritance, since I can select the implementation of a method using that first argument (e.g. on doitImpl)<br>

- base and derived classes see the same member data<br>- Implementations of &#39;InternalAPI&#39; can reference each other through the PublicAPI interface.<br><br>Admittedly it&#39;s a rather vague question. I wonder if there are any articles out there showing how to reformulate problems solved using C++-style object models into Haskell programs? After all, it&#39;s hardly as if the C++ model is particularly elegant...<br>

<br>thanks,<br><br>David<br><br>