[GHC] #14806: Officially sanction certain unsafeCoerce applications with unboxed unary tuples
GHC
ghc-devs at haskell.org
Wed Apr 25 18:38:27 UTC 2018
#14806: Officially sanction certain unsafeCoerce applications with unboxed unary
tuples
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: feature request | Status: new
Priority: normal | Milestone: 8.6.1
Component: Documentation | Version: 8.2.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by dfeuer):
Consider
{{{#!hs
adjust, adjust' :: (a -> a) -> Seq a -> Seq a
}}}
The lazy version can leak memory, but it's been around for years so we
need to support it. The study version is efficient. Both versions can be
defined using a more general operation:
{{{#!hs
adjust# :: (a -> (# a #)) -> Int -> Seq a -> Seq a
adjust f = adjust# (\x -> (# f x #))
adjust' f = adjust# (\x -> let !x' = f x in (# x' #))
}}}
`adjust#` allows the given function to perform as much work as it wants,
then suspend as much further work as it wants. The definitions of `adjust`
and `adjust'` above add a closure allocation and a bit of indirection over
the equivalent direct definitions, unless we inline and duplicate code.
For `adjust`, which already leaks memory, that's tolerable. For `adjust'`,
it's not. What can we do? Define
{{{#!hs
adjust' f = adjust# (unsafeCoerce f)
}}}
That should just work. Since the result of applying `f` is interested by
`adjust#` as an unboxed unary tuple, it gets forced.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14806#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list