[Haskell-cafe] Splitting data and function declarations over
multiple files
Peter Verswyvelen
bugfact at gmail.com
Thu Oct 1 04:45:55 EDT 2009
I'm not sure if I understand what you mean with this co-algebraic approach,
but I guess you mean that functions - like move - don't work directly on any
datatype; you need to provide other functions that give access to the data.
But that's basically what type classes do no? And that's also related to my
earlier post of "strong duck typing" in Haskell.
At least also in C#, that's the way I usually write code that works on any
type, just make an interface or pass in a delegate. I also know that my OO
background keeps pushing me in the wrong direction when it comes to Haskell
;-)
The collision handling approach is always interesting :) In OO this is
usually solved using multi-methods or visitors:
http://en.wikipedia.org/wiki/Multiple_dispatch. What I usually did in old
games of mine to handle collisions is not look at the type, but at the
"collision specific features" of a type (which are again functions that
extract information from the object), and that is most likely again the
co-algebraic approach?
On Wed, Sep 30, 2009 at 9:15 PM, Luke Palmer <lrpalmer at gmail.com> wrote:
> On Wed, Sep 30, 2009 at 9:54 AM, Peter Verswyvelen <bugfact at gmail.com>
> wrote:
> > I guess this is related to the expression problem.
> > Suppose I have a datatype
> > data Actor = Ball ... | Paddle ... | Wall ...
> > and a function
> > move (Ball ...) =
> > move (Paddle ...) =
> > move (Wall ...) =
> > in Haskell one must put Actor and move into a single file.
> > This is rather cumbersome if you work with multiple people or want to
> keep
> > the files small and readable.
> > Surely it is possible to use type classes, existentials, etc to split the
> > data type into multiple ones, but that's already advanced stuff in a
> sense.
>
> You can do it without type classes and existentials. The
> functionality you want is already supported by Haskell, you just have
> to let go of your syntactical expectations. The trick is that you
> should rewrite your data type not as an algebra (a set of
> constructors), but as a coalgebra (a set of projections).
>
> Let's say your two open functions are:
>
> move :: Actor -> Actor
> isAlive :: Actor -> Bool
>
> This gives rise to the definition of an Actor type:
>
> data Actor = Actor { move :: Actor, isAlive :: Bool }
>
> And then the alternatives of your open data type are just values of type
> Actor:
>
> ball :: Vector -> Vector -> Actor
> ball pos vel = Actor {
> move = ball (pos + vel) vel,
> isAlive = True
> }
>
> etc.
>
> This trick works well until you get to the encoding of functions that
> pattern match on multiple Actors at the same time. As far as I can
> tell, that cannot be encoded in this style in any reasonable way.
> Such functions must be rephrased in a coalgebraic style; i.e. instead
> of asking about constructors, using projection functions it knows are
> available.
>
> So for example instead of implementing "collide" by asking about
> pairs, add functions which report a shape function and a normal, or
> whatever your collide algorithm needs from shapes.
>
> You would probably end up having to do this anyway even with your
> proposed extension, because watch:
>
> partial data Actor = Ball ...
>
> collide (Ball ...) (Ball ...) = ...
> collide (Ball ...) x = ...
>
> We don't know about any other constructors, so the second line has to
> contain a pattern-free x. So you would have to use projection
> functions to get any information about it, exactly as you would when
> you're writing in the coalgebraic style.
>
> So, Yes! Haskell can do that!
>
> Luke
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20091001/04a3d134/attachment.html
More information about the Haskell-Cafe
mailing list