Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8947125
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T12:40:27+00:00 2026-06-15T12:40:27+00:00

Since newtype s are effectively removed during compilation, they don’t have thunks, just values.

  • 0

Since newtypes are effectively removed during compilation, they don’t have thunks, just values. So what happens if I ask for its WHNF using rseq? For example in

Sum (lengthyComputation :: Int) `using` rseq

where Sum is defined as

newtype Sum a = Sum { getSum :: a }

will lengthyComputation get evaluated or not? Is it specified/documented somewhere so that I can count on it?


Update: Let me explain my doubts in more detail. Intuitively one says: “newtype is strict so clearly its WHNF is the WHNF of what’s wrapped inside”. But I feel this is a very imprecise shortcut and the reasoning is not so clear. Let me give an example:

For standard data types, WHNF can defined as a form where we know which constructor was used for constructing the value. If, for example, we didn’t have seq, we could create our own

seqMaybe :: Maybe a -> b -> b
seqMaybe Nothing  = id
seqMaybe _        = id

and similarly for any data type, just by pattern matching on one of its constructors.

Now let’s take

newtype Identity a = Identity { runIdentity :: a }

and create a similar seqIdentity function:

seqIdentity :: Identity a -> b -> b
seqIdentity (Identity _)  = id

clearly, nothing is forced to WHNF here. (After all, we always know what constructor was used.) After compilation, seqIdentity will be identical to const id. In fact, it isn’t possible to create polymorphic seqIdentity such that it would force evaluation of a value wrapped inside Identity! We could define WHNF a of a newtype to be simply the value unmodified, and it would be consistent. So I believe the question is, how is WHNF defined for newtypes? Or is there no rigorous definition, and the behavior “it’s the WHNF of what’s inside” is simply assumed as something obvious?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T12:40:28+00:00Added an answer on June 15, 2026 at 12:40 pm

    Per the section on Datatype renamings in the report,

    Unlike algebraic datatypes, the newtype constructor N is unlifted, so that N ⊥ is the same as ⊥.

    Here

    Sum ⊥ = ⊥
    

    so the weak head normal form of a newtype is the WHNF of the wrapped type, and

    Sum (lengthyComputation :: Int) `using` rseq
    

    evaluates lengthyComputation (when the entire expression is evaluated, a mere binding

    let x = Sum (lengthyComputation :: Int) `using` rseq
    

    of course doesn’t, but that is the same without the newtype constructor).

    The defining equations for seq are

    seq ⊥ b  =  ⊥
    seq a b  =  b, if a ≠ ⊥
    

    and hence

    seq (Sum ⊥) b = ⊥
    

    and in

    seq (lengthyComputaton :: Int) b
    

    the seq is required to find out (sorry for the anthropomorphism) whether lengthyComputation :: Int is ⊥ or not. To do that, it must evaluate lengthyComputation :: Int.


    Re update:

    newtypes are unlifted, that means that the constructor is not a value constructor semantically (only syntactically). Pattern-matching on a newtype constructor is, in contrast to pattern matching on a data constructor not strict. Given

    newtype Foo a = Foo { unFoo :: a }  -- record syntax for convenience below
    

    a “pattern match”

    function :: Foo a -> Bar
    function (Foo x) = whatever x
    

    is completely equivalent to

    function y = let x = unFoo y in whatever x
    

    The match always succeeds, and evaluates nothing. The constructor only coerces the type and “pattern matching” on it un-coerces the type of the value.

    seq is magic, it cannot be implemented in Haskell. You can write a function that does the same as seq for a data type, like your seqMaybe above, in Haskell, but not for a (polymorphic) newtype, because “pattern matching” on the newtype constructor is not strict. You would have to match on the constructor(s) of the wrapped type, but for a polymorphic newtype, you don’t have them.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Since I have no errors I don't know if this is the right place
Since now I have only used plugin for editing and the way I use
My use is pretty complicated. I have a bunch of objs and they are
In an Array subclass (just an array that does some coercing of input values)
Since i'm writing a game in RoR, i need to have a game loop
Since the readers don't change anything, why we need ReaderLock?
since memcpy should be highly optimized nowadays, does it still make sense to optimize
Since regular jQuery animations are not fluent on iOS ( .hide() , slideDown() ),
since today im facing a strange problem. When i start my app in my
Since I am developing an iOS >= 5.0 application, I am trying to change

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.