{-# LANGUAGE OverloadedStrings #-} -- | An illustration of phantom types. module Sanitize ( Input, Safe, Unsafe -- don't export In! , input, sanitize, store -- don't export addToDB! ) where import Data.Text (Text,pack,unpack,replace) -- Data types to represent unvalidated vs. validated data. data Unsafe -- NOTE: no data constructors! data Safe -- just using these for their types -- | The type variable 'a' is a "phantom" type. -- It doesn't appear as an argument to any data constructor. newtype Input a = In Text deriving (Eq,Show) -- | Create new unsanitized input. input :: String -> Input Unsafe input = In . pack -- | Sanitize an input by adding missing noses to smileys. sanitize :: Input Unsafe -> Input Safe sanitize (In t) = In (replace ":)" ":-)" t) -- | Store validated input in the database. store :: Input Safe -> IO () store (In t) = addToDB t -- | Add a validated input to the database (or pretend to at least). addToDB :: Text -> IO () addToDB t = putStrLn $ unpack ("Storing: " <> t)