[Haskell-cafe] category design approach for inconvenient concepts

Alexander Solla alex.solla at gmail.com
Wed Dec 19 17:20:05 CET 2012


On Tue, Dec 18, 2012 at 11:53 PM, Christopher Howard <
christopher.howard at frigidcode.com> wrote:

> I really like the idea that all
> parts of my program could be cleanly and systematically composed from
> smaller pieces, in some beautiful design patter. Many of the problems in
> my practical programming, however, are not like the examples I have seen
> (nice pipes or unidirectional calculations) but rather complex fitting
> together of components. E.g., space ships are made up of guns + engines
> + shields + ammo. Different kinds of space ships may use the same kind
> of guns (reusable components) but some wont. Some will have many guns,
> some will have none.
>

So, suppose we have the types:

    data Gun = Gun { requiresAmmo :: Ammo }
    data Engine = ...
    data Ammo = ...
    data Shield = ...

Now, we can build up a space ship in two basic ways:

    type SpaceShip = ([Gun], [Engine], [Shield], [Ammo])
    mkSpaceShip :: [Gun] -> [Engine] -> [Shield] -> [Ammo] -> SpaceShip

or we can define a data type:

    data SpaceShip = SpaceShip [Gun] [Engine] [Shied] [Ammo]

or other variations.  Note that, as morphisms, mkSpaceShip and 'SpaceShip'
are "isomorphic", insofar as the objects they build are different
representations of the same data -- both are "product" types.  In any case,
note that some spaceships can have lots of engines, and others can have
none.

Now, suppose we want a spaceship to actually do something.  In particular,
we might worry about pirate space ships:

   type PirateShip = SpaceShip

and worry about whether your speedy ship can deal with them effectively.
 How would we model this?  Here is an example:

   simulateBattle :: SpaceShip -> PirateShip -> Bool
   simulateBattle s@(SpaceShip gs es ss as) p@(SpaceShip gs' es' ss' as') =
        if es `subset` es' then mustFight s p
                                 else True -- Your ship ran away

   mustFight :: SpaceShip -> PirateShip -> Bool
   mustFight = undefined -- encode semantics about guns, shields, weight,
etc here

We claim that simulateBattle is a "morphism scheme" -- we can /say/ that it
is a morphism from a variety of categories to a variety of categories.  For
example, by rearranging, we can view it as a morphism from
     (SpaceShape -> PirateShip) to Bool (as I said elsewhere, this kind of
morphism isn't particularly useful to a programmer, since we can't analyze
a function to produce a Bool -- being able to do so would mean we have
solved the Halting problem)

or from
     SpaceShip to (PirateShip -> Bool)
or from (SpaceShip, PirateShip) to Bool
or from (SpaceShip) to (PirateShip, Bool)

Note that these choices have different representations as data structures,
and that these structures might have very different properties in terms of
space/time usage.

Compositionality isn't "an" architecture.  It's a property that lets us
transform compositional architectures into other compositional
architectures, while still maintaining the semantics we want.  There are no
"surprises" about the "meaning" of any of the simulateBattle types, even
though their values might behave differently in space and time, because of
the different data structures in play.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20121219/a96ddbec/attachment.htm>


More information about the Haskell-Cafe mailing list