newtype wrapper idiom

3 views
Skip to first unread message

Francesco Lazzarino

unread,
Jun 26, 2012, 9:44:55 PM6/26/12
to gainesvil...@googlegroups.com
newtype T a = T { getT::a }

this means that the programmer wants a new type based on whatever a is, ghc will be efficient and use just a bit more resources than dealing with a, but to the programers point of view there is a new type that they use orthoganal to the typeclasses of a.

also the constructor T a :: T a, lets you (un)wrap an a.

and the function getT :: T a -> a, lets you extract the wrapped value.
is this just a convention instead of relying on a deconstructive bind? \t -> let T a = t in a should be equivalent to getT right?

am i missing something?

Brian Lewis

unread,
Jun 27, 2012, 7:17:29 AM6/27/12
to gainesvil...@googlegroups.com
I think you can only write

> getT' :: T a -> a
> getT' (T a) = a

if you have access to T the constructor. I think in my libraries I
usually don't export stuff like that.

> is this just a convention instead of relying on a deconstructive bind?
> *\t -> let T a = t in a* should be equivalent to *getT* right?

I think so, if the constructor is exported. But if the innards of T
change, you have to change code.

Ian Taylor

unread,
Jun 27, 2012, 8:08:14 AM6/27/12
to gainesvil...@googlegroups.com
On 6/26/12 9:44 PM, Francesco Lazzarino wrote:
newtype T a = T { getT::a }

this means that the programmer wants a new type based on whatever a is, ghc will be efficient and use just a bit more resources than dealing with a, but to the programers point of view there is a new type that they use orthoganal to the typeclasses of a.
ghc will treat T as distinct from a, but the compiler result will treat its usage as a so there is no run-time penalty for wrapping the type.

also the constructor T a :: T a, lets you (un)wrap an a.
and the function getT :: T a -> a, lets you extract the wrapped value.
is this just a convention instead of relying on a deconstructive bind? \t -> let T a = t in a should be equivalent to getT right?

am i missing something?

newtype T a = T { getT :: a }
is just sugar for
newtype T a = T a

getT :: T a -> a
getT (T a) = a

You may not want to export the constructor in a module. For instance, if you decided to implement DayOfWeek with an Int.

newtype DayOfWeek = DayOfWeek Int

-- smart constructor
mkDayOfWeek dow
  | 0 < dow && dow <= 7 = DayOfWeek dow
  | otherwise = error "invalid day of week"

http://www.haskell.org/haskellwiki/Smart_constructor
signature.asc
Reply all
Reply to author
Forward
0 new messages