[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