
Hello there, I've been thinking on different approaches to constraint particular functions to a particular constructor of an ADT in order to reduce representation of invalid states. Say for example I've this types: data Address = Address { ... } newtype Email = Email String data Package = Package { ... } data EmailMsg = EmailMsg { ... } data User = RealUser Address | VirtualUser Email And I would like to implement two functions: deliverPackage :: User -> Package -> IO Bool sendEmail :: User -> EmailMsg -> IO () I would like to constraint both deliverPackage and sendEmail to receive only the semantically correct constructor of User. I know of an approach I could use, that is wrapping each constructor in it's own newtype, and create some smart constructor that way, that approach works, but I find it rather verbose. Is there any other well known approach to deal with this scenarios?