[Haskell-cafe] Client-extensible heterogeneous types
Alexander Solla
ajs at 2piix.com
Tue Oct 12 18:28:32 EDT 2010
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 think that letting the programmer design domain
specific control structures is rather the point of Haskell. 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.
An OO class hierarchy is a very specific functor over objects (which
attaches methods to objects). 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.
-- 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
-- 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))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20101012/87be238b/attachment.html
More information about the Haskell-Cafe
mailing list