[Haskell-cafe] data/newtype examples

Richard Eisenberg lists at richarde.dev
Fri May 6 13:46:06 UTC 2022

Hi Johannes,

Fun examples.

For me, the key insight that allowed me to anticipate behaviors here is that Haskell's `case` is lazy. That is, `case undefined of _ -> ()` will evaluate to `()`. Instead, certain patterns force the scrutinee, but it's really the *patterns* that do this forcing, not the `case` itself. In light of this observation -- and knowing that newtypes are completely erased at runtime -- you can then predict the behavior of these examples. (I won't say more, so as not to spoil the fun of experimenting for others.)

If you're teaching these examples, you may also want to consider `data S = S !Bool`, whose behavior in these is different from both D and N.


> On May 6, 2022, at 3:19 AM, Johannes Waldmann <johannes.waldmann at htwk-leipzig.de> wrote:
> Dear Cafe -
> I wanted a quick example (for teaching)
> that shows a difference between data and newtype.
> You'd think that `newtype` makes things more strict,
> so we'd see more exceptions. 
> Then try the following, and try to guess the semantics beforehand:
> ghci> data D = D Bool
> ghci> case D undefined of D x -> ()
> ghci> case undefined of D x -> ()
> ghci> newtype N = N Bool
> ghci> case N undefined of N x -> ()
> ghci> case undefined of N x -> ()
> What examples do you use?
> I'm interested both in simple ones,
> and confusing/obfuscated ones.
> Yes I know I can
> ghci> seq (D undefined) ()
> ()
> ghci> seq (N undefined) ()
> *** Exception: Prelude.undefined
> but that `seq` is extra magic that needs to be explained.
> Well, perhaps I should.
> To show that I've done some homework here: 
> the primary source of truth is the Haskell Language Report 
> (well hidden at the bottomest end of https://www.haskell.org/documentation/)
> and it uses (in 4.2.3 Datatype Renamings) the concept
> of "equivalent to bottom". Then 6.2 Strict Evaluation
> shows how to test that with `seq` (without mentioning newtype,
> and that's fine since the Report is not a tutorial).
> This suggests that `seq` is really the way to go here.
> There are examples for data/newtype/case combined
> in 3.17.2 Informal Semantics of Pattern Matching 
> but they distinguish between
> newtype N = N Bool  and  data    D = D !Bool  (with a bang).
> - J.W.
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.

More information about the Haskell-Cafe mailing list