[Haskell-cafe] Abstraction in data types

Job Vranish job.vranish at gmail.com
Thu Mar 18 12:54:42 EDT 2010

A phantom type might do what you want:

-- notice the type parameter on point that isn't used in the type
data Point  a  = Cartesian (Cartesian_coord, Cartesian_coord)
                         | Spherical (Latitude, Longitude)

-- make some dummy types
data SphericalP
data CartesianP

--make some constructors that add a restriction to the phantom type
-- notice the CartesianP type restriction, this isn't needed but allows us
to restrict our type later if we want
mkCartesian :: (Cartesian_coord, Cartesian_coord) -> Point  CartesianP
mkCartesian = Cartesian

mkSherical :: (Latitude, Longitude) -> Point  SphericalP
mkSherical = Spherical

type Center = Point
type Radius = Float

-- now the shape type doesn't care which type of point you have, but
requires that all the points are the same
data Shape  a = Circle Center Radius
                           | Polygon [Point a]

The main problem here, is that you want to hide the Cartesian and Spherical
constructors and only use mkCartesian and mkSherical to make Points (so that
they have the proper restrictions). But this prevents you from using pattern
matching where you have the constructors hidden.

GADTs however will solve that:

data Point a where
  Cartesian :: (Cartesian_coord, Cartesian_coord) -> Point CartesianP
  Spherical :: (Latitude, Longitude)-> Point SphericalP

Hope that helps :)

- Job

On Thu, Mar 18, 2010 at 12:20 AM, Darrin Chandler
<dwchandler at stilyagin.com>wrote:

> Hi,
> Trying to get up to speed in Haskell, I'm playing with doing some
> abstraction in data types. Specifically, I have this:
> type Cartesian_coord = Float
> type Latitude  = Float
> type Longitude = Float
> data Point      = Cartesian (Cartesian_coord, Cartesian_coord)
>                | Spherical (Latitude, Longitude)
> type Center = Point
> type Radius = Float
> data Shape      = Circle Center Radius
>                | Polygon [Point]
> This obviously stinks since a Polygon could contain mixed Cartesian and
> Spherical points. Polygon needs to be one or the other, but not mixed.
> I could define seperate types for Cartesian and Spherical and seperate
> CartesianPoly and SphericalPoly, but that doesn't seem very elegant and
> also increases as I add more coordinate systems and shapes. I read a
> little on GADTs, et al, but I'm not sure if that's what I want for this
> or not.
> Any help appreciated!
> --
> Darrin Chandler            |  Phoenix BSD User Group  |  MetaBUG
> dwchandler at stilyagin.com   |  http://phxbug.org/      |
> http://metabug.org/
> http://www.stilyagin.com/  |  Daemons in the Desert   |  Global BUG
> Federation
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100318/95bf3b49/attachment.html

More information about the Haskell-Cafe mailing list