One of the programming exercises I keep evolving as I learn Haskell is a toy 2D shape editor with four primitives:<br><br>data Shape =   Circle   {origin::Pt2, radius::Float}<br>                       | Square   {origin::Pt2, side  ::Float}<br>
                       | Rect     {origin::Pt2, other ::Pt2}<br>                       | Composite {shapes::[Shape]}<br>                         deriving (Show, Read)<br><br>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.<br>
<br>And the above makes that really easy when you know you&#39;re talking to a Composite. But now I&#39;ve hit an intellectual stumbling point and the books and source I have don&#39;t seem to address it:  I can apply the destructuring command &quot;shapes&quot; defined in the cstr &quot;Composite&quot; to ANY Shape. And if I do that to say a circle, BLAM! Or if I apply &quot;radius&quot; to Rect, BLAM! At runtime. No type checking support (because yes, they&#39;re the same type.)<br>
<br>To me this seems alarming. It means that I can&#39;t reason about the safety of my program based on type checking as I&#39;d like. And none of the answers I can think seem at all elegant:<br><br>- 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.<br>
<br>- I could hack run time type checking using the ctsr info in &quot;show&quot;. But again I&#39;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.<br>
<br>..So what is the Haskell idiom for dealing with this??? In fact I suppose I&#39;m asking two questions:<br><br>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?)<br>
<br>2. How can one use compile time checking or (less good) coding practices to eliminate the possibilty of such runtime exceptions?<br><br>And come to think of it<br><br>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&#39;ve looked at so far seem to do a tolerable job. The best of them present an adequate &quot;on rails&quot; 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&#39;d know exactly what to do. Admittedly the C++ solutions wouldn&#39;t be pretty, but anything the compiled would be safe to run (unless I went to great efforts otherwise..) <br>
<br>