Search code examples
haskellstate-monadnewtype

Why is newtype commonly used instead of type with the state monad


Almost all of examples I've seen of the State Monad have been wrapped inside a newtype.

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.State
import Control.Applicative

data Bazzar 
  = Bazzar {
    valueOne :: Int      
  , valueTwo :: Int      
  }

newtype BazState a = BazState { unBazify :: State Bazzar a } 
  deriving (Functor, Applicative, Monad, MonadState Bazzar)

Are there any reasones why I shouldn't just make a type alias?

type BazState a = State Bazzar a

I realize the purpose of newtype is to differentiate between two different uses for the same type of data structure, like reimplementing type classes for existing types, or if you want to differentiate your use of the type from normal behavior. Or implement additional typeclasses for use of that class

If you're not doing any of the stuff mentioned above, isn't using newtype in this case just needless indirection?


Solution

  • Other than being able to define instances for a newtype, you can use it as a "closed constructor" API for your library. That way you export a single type without any constructors, along with functions that act as primitives and combinators so that users of your library can't construct invalid values of your type. It also means that if you're careful enough, you can change the underlying structure without breaking the outward facing API. A great example of this comes from Neil Mitchell, who said in a recent post about modifying the Shake build system to use the Continuation monad:

    The cool thing about Haskell is that I've been able to completely replace the underlying Shake Action monad from StateT/IO, to ReaderT/IO, to ReaderT/ContT/IO, without ever breaking any users of Shake. Haskell allows me to produce effective and flexible abstractions.