This makes T fully abstract, which is what I'm trying to avoid. Private types provide an intermediate level of abstraction. The real example I have involves defining a type with numerous constructors (or a record with numerous fields), and I'd like to avoid writing all the corresponding destructors. Even if I did do this, it burdens clients of the module by requiring them to use the alternative destructors. I think the feature I'm looking for is "guarded constructors", but to my knowledge there is no such thing. On Thu, Apr 8, 2010 at 3:42 PM, Stephen Tetley <stephen.tetley@gmail.com>wrote:
Hi
I don't think there is a direct equivalence. You can make T an opaque type using a module where you do not export the constructor. However, you can't then pattern match on the type so you have to supply a destructor - here called unT. Any module that imports XYZ only sees the type T, the 'handmade' constructor makeT and the destructor unT:
module XYZ ( T, -- this does not export the constructor unT makeT
) where
data T = PrivateT Int deriving (Eq,Show)
unT :: T -> Int unT (PrivateT i) = i
-- Add any checking you want here... makeT :: Int -> T makeT i = PrivateT i