From HaskellWiki
Jump to navigation Jump to search

A newtype declaration creates a fresh type with the same representation as an existing ("underlying") type. The most common reasons they are used are:

  • providing additional type safety, by making different uses of the same underlying type incompatible,
  • creating abstract data types,
  • permitting alternative or additional typeclass instances to be declared for the new type.


The syntax is similar to that of data declarations:

--      name of the new type
--      |          name of its value constructor
--      |          |          underlying type
--      |          |          |
--      v          v          v
newtype Username = MkUsername String
  deriving (Eq, Ord, Read, Show)

-- may also have type parameters
newtype Parser a = MkParser (String -> Maybe (String, a))

-- or record syntax
newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }

Following the above declarations, we have new type constructors Username, Parser, and StateT, and new value constructors with the following types:

MkUsername :: String                        -> Username
MkParser   :: (String -> Maybe (String, a)) -> Parser a

StateT     :: (s -> m (a, s)) -> StateT s m a
runStateT  :: StateT s m a    -> (s -> m (a, s))

Notice that in the case of StateT, the type constructor and the value constructor have the same name: some find that this is a helpful mnemonic, while others find it confusing, and insist on something like the Mk prefix used above (both these conventions also exist for single-constructor data declarations).

By contrast to data declarations, which may have several value constructors, each with zero or more fields containing values of other types, newtypes may only have exactly one constructor, and that constructor must have exactly one field (which, as shown above, is permitted to be a record field). This ensures that the new type and the underlying type – the type of that single field of that single constructor – are in direct correspondence.


So, if a newtype declaration can only create a type that's exactly the same as an existing type, why bother at all? Let's return to the three bullet points given at the start of the article:

Additional type safety

Sometimes you use one type for many different purposes, and it's important not to get them mixed up.