On 1/14/13 2:47 PM, Stephen Paul Weber wrote:
Somebody claiming to be Simon Peyton-Jones wrote:
* For x1 we can write map MkAge x1 :: [Age]. But this does not
follow the newtype cost model: there will be runtime overhead from
executing the map at runtime, and sharing will be lost too. Could GHC
optimise the map somehow?
My friend pointed out something interesting:
If GHC can know that MkAge is just id (in terms of code, not in terms of
type), which seems possible, and if the only interesting case is a
Functor, which seems possible, then a RULE fmap id = id would solve
this. No?
The problem is precisely that the types don't line up, so that rule
won't fire. A more accurate mental model is that when we write:
newtype Foo = MkFoo { unFoo :: Bar }
the compiler generates the definitions:
MkFoo :: Bar -> Foo
MkFoo = unsafeCoerce
unFoo :: Foo -> Bar
unFoo = unsafeCoerce
(among others). So the rule we want is:
fmap unsafeCoerce = unsafeCoerce
Except, there are functions other than fmap which behave specially on
identity functions. Another major one is (.) where newtypes (but not id)
introduce an eta-expansion that can ruin performance.
It strikes me that the cleanest solution would be to have GHC explicitly
distinguish (internally) between "identity" functions and other
functions, so that it can ensure that it treats all "identity" functions
equally. Where that equality means rewrite rules using id, special
optimizations about removing id, etc, all carry over to match on other
"identity" functions as well.
--
Live well,
~wren
_______________________________________________
Glasgow-haskell-users mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users