Consider the following
data Predicate = Pred Name Arity Arguments
type Name = String
type Arity = Int
type Arguments = [Entity]
type Entity = String
This would allow the creation of
Pred "divides" 2 ["1", "2"]
Pred "between" 3 ["2", "1", "3"]
but also the "illegal"
Pred "divides" 2 ["1"]
Pred "between" 3 ["2", "3"]
"Illegal" because the arity does not match the length of the argument list.
Short of using a function like this
makePred :: Name -> Arity -> Arguments -> Maybe Predicate
makePred n a args | a == length args = Just (Pred n a args)
| otherwise = Nothing
and only exporting makePred from the Predicate module, is there a way to enforce the correctness of the value constructor?