
On 2004-11-01 at 23:01+0100 Benjamin Franksen wrote:
On Monday 01 November 2004 21:51, Jon Fairbairn wrote:
Put the data declaration in a module, export the type, but
not the constructor you want to hide:
module Shape (Shape(Square), circle) where
Since we were talking about 'what can one do with a constructor as compared with a function', it should be mentioned that this also has a disadvantage: you loose pattern matching outside the module. I.e. no longer can say
... case x of Circle radius -> ... Square edge -> ...
BTW, would it be possible (in principle) to allow constructor export 'read-only', so matching against a constructor is allowed but not constructing a value?
I don't see why not. To add something to the debate about what Circle /is/, I'd like to mention that the declaration data Shape = Circle Double | Square Double is a convenience that declares three new names (Shape, Circle and Square), but five entities. There's Shape: a type, Circle, Square:: Double -> Shape: constructor functions, and Circle, Square:: Shape -> (Double -> t) -> t -> t: destructor functions. The first three are available for general use by the programmer, but the last two are hidden in the works of pattern matching. I think this is what confuses things. In all contexts bar pattern matching and export lists, Circle and Square refer to the constructor functions (and they really are just functions in these contexts). In patterns they indirectly refer to the destructor functions, and in export lists to both. I'd like to see the separation made more accessible, and if this were done, one could export whatever combination of the entities one desired. I hesitate to raise the question of what syntax we might choose to represent this for fear of invoking Wadler's law. Jón -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk