[Haskell-cafe] Re: ANN: First Monad Tutorial of the Season

Ryan Ingram ryani.spam at gmail.com
Mon Aug 25 14:36:12 EDT 2008

On Mon, Aug 25, 2008 at 5:33 AM, Hans van Thiel <hthiel.char at zonnet.nl> wrote:
> The books I use for reference, the Craft and SOE, don't seem to mention
> this. I have to confess, I don't really understand the difference
> between newtype and data. Again, an explanation would be appreciated.

A newtype has no run-time representation; it is an entity at
type-checking time, nothing more.  data, on the other hand, has a
runtime representation.

> data D = D Int
> newtype N = N Int

> d1 = D 1
> n1 = N 1
> i1 = 1 :: Int

In memory at runtime, these look different; n1 looks exactly the same
as i1.  We can represent them both in this way:

lit = 1 :: Int#  (unlifted, unboxed int)
i1 = { tag = I#, content -> lit }
n1 = { tag = I#, content -> lit }

But d1 is different; it looks like this:

d1 = { tag = D, content -> i1 }

There's an extra level of indirection between the "data" version and
the contents.  What does this mean?  Well, in particular, you get
different behavior in a couple of cases when dealing with "error" (or
infinite loops):

> u = error "u"
> du = D (error "du")
> nu = N (error "nu")

> ignoreD (D _) = "ok!"
> ignoreN (N _) = "ok!"

ignoreD u => error "u"
ignoreN u => "ok!"

ignoreD looks for the "D" tag on its argument, which forces its
argument to be evaluated.  That fails and you get an error.
But "unwrapping" the newtype doesn't do anything; it's just there for
typechecking.  So there is no error in that case.

  -- ryan

More information about the Haskell-Cafe mailing list