More speed please!

Simon Peyton-Jones simonpj at
Fri Mar 16 13:49:46 EDT 2007

| newtype Put a = Put {
|         runPut :: (a -> {-# UNPACK #-} !Buffer -> [B.ByteString])
|                      -> {-# UNPACK #-} !Buffer -> [B.ByteString]
|     }

OK I'm beginning to get it.


        data Foo a = MkFoo !a

means this: define the MkFoo constructor thus

        MkFoo x = x `seq` :MkFoo x

where :MkFoo is the "real constructor".  (Well that's what I think it means; see Ian's Haskell Prime thread!)

Now you are proposing that

        data Bar a = MkBar (!a -> a)

means this:

        MkBar f = :MkBar (\x. x `seq` f x)

That is, even if the argument to MkBar is a lazy function, when you take a MkBar apart you'll find a strict function.

I suppose you can combine the two notations:

        data Baz a = MkBaz !(!a -> a)
        MkBaz f = f `seq` :MkBaz (\x. x `seq` f x)

Interesting.  Is that what you meant?  An undesirable consequence would be that
        case (MkBar bot) of MkBar f -> f `seq` 0
would return 0, because the MkBar constructor puts a lambda inside.  This seems bad.  Maybe you can only put a ! inside the function type if you have a bang at the top (like MkBaz).


More information about the Glasgow-haskell-users mailing list