Opaque types

Opaque types are types where a custom type itself is public and can be used by other modules, but the constructors for the type are private and can only be used by the module that defines the type. This prevents other modules from constructing or pattern matching on the type.

This is useful for creating types with smart constructors. A smart constructor is a function that constructs a value of a type, but is more restrictive than if the programmer were to use one of the type's constructors directly. This can be useful for ensuring that the type is used correctly.

For example, this PositiveInt custom type is opaque. If other modules want to construct one they have to use the new function, which ensures that the integer is positive.