[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