
| newtype Put a = Put { | runPut :: (a -> {-# UNPACK #-} !Buffer -> [B.ByteString]) | -> {-# UNPACK #-} !Buffer -> [B.ByteString] | } OK I'm beginning to get it. Writing 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) means 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). Simon