<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 12, 2010, at 4:24 AM, Jacek Generowicz wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">I can't see a Haskell solution which combines both of these orthogonal<br>features without losing the benefits of the type system. (For example,<br>I could create my own, weak, type system with tags to identify the<br>type and maps to do the dispatch.)</span></blockquote></div><br><div>Is there any particular reason why you want to actually to mirror Python code? &nbsp;I think that letting the programmer design domain specific control structures is rather the point of Haskell. &nbsp;Instead of relying on a one-sized fits all solution (which only really fits one kind of problem), you write your own. &nbsp;And it is typically easier to write the control structure than it is to implement it using the OO patterns, because of the notion of irreducible complexity. &nbsp;For example, the Factory pattern constructs a functor. &nbsp;You can write the essential semantics of doing this with a single Functor instance, instead of writing multiple classes which implement the semantics, while relying on implicit, and possibly ill-fitting semantics of method dispatch. &nbsp;The other OO patterns make this objection stronger. &nbsp;If you can write a UML diagram, you can turn it into a commutative diagram, and write less code by implementing its arrows.</div><div><br></div><div>An OO class hierarchy is a very specific functor over objects (which attaches methods to objects). &nbsp;Haskell provides the Functor type class. &nbsp;Write your generic functions for specific functors:</div><div><br></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">-- The varying "input" types. &nbsp;Will be attached to arbitrary values by the Functor instance.</font></div><div><span class="Apple-style-span" style="font-family: Courier; "><br></span></div><div><font class="Apple-style-span" face="Courier"></font><span class="Apple-style-span" style="font-family: Courier; ">data A = A<span class="Apple-tab-span" style="white-space:pre">        </span>-- Variant 1</span></div><div><font class="Apple-style-span" face="Courier">data B = B<span class="Apple-tab-span" style="white-space:pre">        </span>-- Variant 2</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">-- Some normalized Output type.</font></div><div><font class="Apple-style-span" face="Courier">data Output = Output</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">-- The new control structure. &nbsp;</font></div><div><font class="Apple-style-span" face="Courier">data Attaches a = AttachesA A a</font></div><div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| AttachesB B a</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">-- Stick your conditional (varying) semantics in here. &nbsp;Corresponds to heterogeneousProcessor. &nbsp;</font></div><div><font class="Apple-style-span" face="Courier">-- The output presumably depends on whether A or B is attached, so this function is not equivalent&nbsp;</font></div><div><font class="Apple-style-span" face="Courier">-- to something of the form fmap (f :: a -&gt; Output) (attaches :: Attaches a)&nbsp;</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">runAttaches :: Attaches a -&gt; Attaches Output</font></div><div><font class="Apple-style-span" face="Courier">runAttaches = undefined</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">-- This corresponds roughly to heterogeneousProcessor(heterogeneousContainer):</font></div><div><font class="Apple-style-span" face="Courier">processedOutputs :: [Attaches a] -&gt; [(Attaches Output)]</font></div><div><font class="Apple-style-span" face="Courier">processedOutputs as = fmap runAttaches as</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier">-- Functor instance. &nbsp;Now you have a way to treat an (Attaches a) value just like you would an a. (modulo calling fmap)</font></div><div><font class="Apple-style-span" face="Courier">instance Functor Attaches where</font></div><div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; fmap f (AttachesA A a) = (AttachesA A (f a))</font></div><div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; fmap f (AttachesB B a) = (AttachesB B (f a))</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><br></div></body></html>