[Haskell-beginners] Type system for constructor preconditions

Bryan Vicknair bryanvick at gmail.com
Thu Jan 17 00:10:18 CET 2013


I'm interested in forcing data passed to a constructor to meet certain
preconditions.  I've seen the wiki entry on smart constructors, and would have
stopped thinking about the problem if hiding the data constructors didn't also
make it impossible to do pattern matching.

Ideally, the type system could do these checks, but we don't have dependent
types so I kept looking.  The pattern below uses the type system to force a
client of the Circle data type to pass in valid (positive) radius.  This isn't
quite what is on the smart constructors wiki page.  Does pattern have a name?
Where can I read more about it?  What are the negatives?

The positives are that when a client goes to create a Circle in their code,
they'll notice that they need to pass a ValidRadius, not just any number, so
then they'll *have* to find a function that gives them a ValidRadius, and thus
will be forced to be semi-informed about what sorts of preconditions exist on
the Circle constructor;  They'll have to deal with the case that validRadius
gives them Nothing.

If we had simply put a comment by the Circle constructor to use a
validateRadius function to make sure their number is valid, they could have
ignored it.


-- In Circle.hs
module Circle (
    Circle (Circle),
    Radius,
    validRadius,
    ValidRadius
    ) where

type Radius = Int
data ValidRadius = ValidRadius Radius deriving (Eq, Show)
data Circle = Circle ValidRadius deriving (Eq, Show)

-- A radius must be positive.
validRadius :: Radius -> Maybe ValidRadius
validRadius x
  | x > 0     = Just $ ValidRadius x
  | otherwise = Nothing



-- In Client.hs
import Circle

r = 3 :: Radius
vr :: ValidRadius
vr = case validRadius r of
          Nothing -> error "Tell UI about bad input"
          Just x  -> x



More information about the Beginners mailing list