[Haskell-beginners] Program reliability and multiple data constructors; polymorphism

Lyndon Maydwell maydwell at gmail.com
Wed Apr 18 18:06:26 CEST 2012

There is some funkyness going on with records there.

You can sidestep the issue by giving each constructor its own type of
argument record:

type Pt2 = (Float, Float)

data Shape =   Circle    CircleData
             | Square    SquareData
             | Rect      RectData
             | Composite CompData
               deriving (Show, Read)

data    CircleData = CircD   {circleOrigin :: Pt2, radius   :: Float}
deriving (Show, Read)
data    SquareData = SquareD {squareOrigin :: Pt2, side     :: Float}
deriving (Show, Read)
data    RectData   = RectD   {bottomLeft   :: Pt2, topRight :: Pt2}
deriving (Show, Read)
newtype CompData   = CompD   {shapes       :: [Shape] }
deriving (Show, Read)

x = shapes $ RectD (0,0) (1,1) -- Throws an error on compile

I'm not sure what is going on in your example, but it seems like each
constructor adds its record argument's fields to a shared record type
or some such magic. Nasty.

On Wed, Apr 18, 2012 at 11:10 PM, umptious <umptious at gmail.com> wrote:
> One of the programming exercises I keep evolving as I learn Haskell is a toy
> 2D shape editor with four primitives:
> data Shape =   Circle   {origin::Pt2, radius::Float}
>                        | Square   {origin::Pt2, side  ::Float}
>                        | Rect     {origin::Pt2, other ::Pt2}
>                        | Composite {shapes::[Shape]}
>                          deriving (Show, Read)
> The intent  is Composites can contain Shapes of any kind, including other
> Composites so that you can apply transformations to a Composite and these
> will be applied to the contained Shapes recursively. So an arm might contain
> a hand which constains a dozen or so Rects. Transform the arm and the hand
> and rects should transform; transform the hand and its rects should
> transform but the not arm. Big deal.
> And the above makes that really easy when you know you're talking to a
> Composite. But now I've hit an intellectual stumbling point and the books
> and source I have don't seem to address it:  I can apply the destructuring
> command "shapes" defined in the cstr "Composite" to ANY Shape. And if I do
> that to say a circle, BLAM! Or if I apply "radius" to Rect, BLAM! At
> runtime. No type checking support (because yes, they're the same type.)
> To me this seems alarming. It means that I can't reason about the safety of
> my program based on type checking as I'd like. And none of the answers I can
> think seem at all elegant:
> - I could use exception handling, but that means carefully checking which
> data declarations are potential bombs and using exceptions only when they
> are involved - hideously error prone - or using exceptions everywhere. Which
> is just hideous.
> - I could hack run time type checking using the ctsr info in "show". But
> again I'd have to know when to use it or use it everywhere. And it seems
> like a ridiculous kludge to bring to a language that has been designed for
> elegance.
> ..So what is the Haskell idiom for dealing with this??? In fact I suppose
> I'm asking two questions:
> 1. How do I re-design this program so it is safe (use class and instance
> maybe, abandoning use of a single data type? but I then have to have
> separate Lists for each type, even if they derived from a common class?)
> 2. How can one use compile time checking or (less good) coding practices to
> eliminate the possibilty of such runtime exceptions?
> And come to think of it
> 3. is there a Haskell book which addresses design and structural problems
> like this one - which I would have thought was both obvious and fundamental
> - because of the books I've looked at so far seem to do a tolerable job. The
> best of them present an adequate "on rails" tour, but none of them seem to
> give you the tools to address issues like this one. Whereas with C++and
> Stroustrupp, Common Lisp and Graham, the Smalltalk book, and I Erlang and
> Armstrong I'd know exactly what to do. Admittedly the C++ solutions wouldn't
> be pretty, but anything the compiled would be safe to run (unless I went to
> great efforts otherwise..)
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners

More information about the Beginners mailing list