Mmmm, let's give a slightly different example:
foo :: Foo -> Int
foo (Foo a) = a + 1
bar :: Int -> Int
bar = foo . Foo
and I'd expect bar to be replaced with (foo `cast` (Int -> Int)) and
inlined, eliminating an allocation. In general, we'd get the equivalent of
the no-allocation versions of GeneralizedNewtypeDeriving instances, so long
as we could write them out for ourselves.
Louis Wasserman
wasserman.louis@gmail.com
http://profiles.google.com/wasserman.louis
On Tue, Jul 13, 2010 at 9:09 AM, Simon Peyton-Jones
It compiles to
lift f d = f (d `cast` blah)
which seems fine to me. Are you unhappy with that?
Simon
*From:* glasgow-haskell-users-bounces@haskell.org [mailto: glasgow-haskell-users-bounces@haskell.org] *On Behalf Of *Louis Wasserman *Sent:* 09 July 2010 03:30 *To:* glasgow-haskell-users@haskell.org *Subject:* Casting + eta reduction
Consider
newtype Foo = Foo Int
lift :: (Int -> a) -> Foo -> a
lift f (Foo x) = f x
Now, I'd expect this to compile with -O2 down to something like
lift f = f `cast` (Foo -> a)
but it doesn't.
It seems that GeneralizedNewtypeDeriving assumes that these two things *are* equivalent, and it just directly casts the class dictionary. The implication would be that that GeneralizedNewtypeDeriving gives more efficient instances than you could *possibly* get if you wrote them by hand, which is very sad.
Louis Wasserman wasserman.louis@gmail.com http://profiles.google.com/wasserman.louis