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?
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 fromStateT/IO
, toReaderT/IO
, toReaderT/ContT/IO
, without ever breaking any users of Shake. Haskell allows me to produce effective and flexible abstractions.