
#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