Paul Rubin
2012-05-19 21:29:11 UTC
I don't know ML and am wondering if it has a solution for an annoying
situation that comes up in Haskell sometimes. I want to enforce a data
invariant using smart constructors, which means using the module system
to limit where new values in the datatype can be introduced. For
example, I might want a number type that tracks whether the number is
prime:
module Foo (Number, mkNumber) where
data Number = Prime Integer | Composite Integer
mkNumber :: Integer -> Number
mkNumber n | isPrime n = Prime n
| otherwise = Composite n
By not exporting the Prime and Composite constructors, the module
prevents someone from making a value like "Composite 5".
The problem is that I'd like outside of the module to be able to pattern
match on the constructors, just not create new values:
case n of
Prime p -> "has no factors";
Composite c -> "is factorable"
but there's no apparent nice way to do this in Haskell (there are some
ugly ways involving adding more types to the module, etc).
Does ML have a way to do this?
Thanks.
situation that comes up in Haskell sometimes. I want to enforce a data
invariant using smart constructors, which means using the module system
to limit where new values in the datatype can be introduced. For
example, I might want a number type that tracks whether the number is
prime:
module Foo (Number, mkNumber) where
data Number = Prime Integer | Composite Integer
mkNumber :: Integer -> Number
mkNumber n | isPrime n = Prime n
| otherwise = Composite n
By not exporting the Prime and Composite constructors, the module
prevents someone from making a value like "Composite 5".
The problem is that I'd like outside of the module to be able to pattern
match on the constructors, just not create new values:
case n of
Prime p -> "has no factors";
Composite c -> "is factorable"
but there's no apparent nice way to do this in Haskell (there are some
ugly ways involving adding more types to the module, etc).
Does ML have a way to do this?
Thanks.