On 2010 Oct 13, at 00:28, Alexander Solla wrote:
On Oct 12, 2010, at 4:24 AM, Jacek Generowicz wrote:
I can't see a Haskell solution which combines both of these
orthogonal
features without losing the benefits of the type system. (For
example,
I could create my own, weak, type system with tags to identify the
type and maps to do the dispatch.)
Is there any particular reason why you want to actually to mirror
Python code?
I don't want to: I merely have a situation in which an OO solution
(not necessarily a good one) immediately springs to mind, while I
didn't see any obvious way to do it in Haskell. (I am sure that this
is my shortcoming, not Haskell's.) I included the Python example lest
my question be too nebulous without it.
I would be delighted to learn approaches which are completely
different to anything offered by OO. In fact, for personal didactic
purposes, being un-OO-like could even be considered to be a goal.
I think that letting the programmer design domain specific control
structures is rather the point of Haskell.
While I don't, at the moment, understand exactly how this is the case,
I do like the sound of it.
Instead of relying on a one-sized fits all solution (which only
really fits one kind of problem), you write your own. 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. For example, the Factory pattern constructs
a functor. 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. The other OO patterns make
this objection stronger. If you can write a UML diagram, you can
turn it into a commutative diagram, and write less code by
implementing its arrows.
Lots of stuff that sounds fascinating, but whose detailed meaning is,
at the moment, beyond my grasp. So let my start off by getting my
teeth into your example code:
An OO class hierarchy is a very specific functor over objects (which
attaches methods to objects).
This sounds very interesting, but, again, I'm having difficulty
understanding *exactly* how that is.
Haskell provides the Functor type class. Write your generic
functions for specific functors:
-- The varying "input" types. Will be attached to arbitrary values
by the Functor instance.
data A = A -- Variant 1
data B = B -- Variant 2
-- Some normalized Output type.
data Output = Output
-- The new control structure.
data Attaches a = AttachesA A a
| AttachesB B a
-- Stick your conditional (varying) semantics in here. Corresponds
to heterogeneousProcessor.
Could you explain this a bit more? heterogeneousProcessor was
extremely boring: its only interesting feature was the dot between
"datum" and "method()" Here it is again:
def heterogeneousProcessor(data):
return [datum.method() for datum in data]
I suspect that runAttaches is (potentially) a lot more interesting
than that!
-- The output presumably depends on whether A or B is attached, so
this function is not equivalent
-- to something of the form fmap (f :: a -> Output) (attaches ::
Attaches a)
runAttaches :: Attaches a -> Attaches Output
runAttaches = undefined
-- This corresponds roughly to
heterogeneousProcessor(heterogeneousContainer):
processedOutputs :: [Attaches a] -> [(Attaches Output)]
processedOutputs as = fmap runAttaches as
Would it be correct to say that runAttaches replaces Python's (Java's,
C++'s etc.) dynamically dispatching dot, but also allows for a greater
variety of behaviour?
Alternatively, would it be interesting to compare and contrast
runAttach to CLOS' generic functions, or even Clojure's arbitrary
method selection mechanism?
-- Functor instance. Now you have a way to treat an (Attaches a)
value just like you would an a. (modulo calling fmap)
instance Functor Attaches where
fmap f (AttachesA A a) = (AttachesA A (f a))
fmap f (AttachesB B a) = (AttachesB B (f a))
[ Aside:
Briefly returning to my original question: I don't see how, if this
were supplied in a library, it would allow clients to inject new
entities into the framework. It all seems to hinge on the Attaches
type, which would be defined in the library, and is not extensible
without modifying the library source code (unless I'm missing
something). Which doesn't diminish my desire to understand what you
are saying, in the slightest.
Can the set of variants usable in this framework be extended without
modifying the original source? ]
Coming back to your statement that "An OO class hierarchy is a very
specific functor over objects (which attaches methods to objects)",
how would we complete your code so that it implements this particular
functor?
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe