[GHC] #14806: Officially sanction certain unsafeCoerce applications with unboxed unary tuples

GHC ghc-devs at haskell.org
Tue Feb 13 21:12:08 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:                    |
-------------------------------------+-------------------------------------
Description changed by dfeuer:

Old description:

> It seems that it should be okay to `unsafeCoerce` between types that wrap
> certain things in unboxed unary tuples and ones that do not. For example,
>
> {{{#!hs
> unsafeCoerce :: (A -> B) -> A -> (# B #)
> unsafeCoerce :: ((# A #) -> B) -> A -> B
> }}}
>
> Generally, I believe `unsafeCoerce :: E1 -> E2` should be okay when the
> only differences are in what is wrapped in an unboxed unary tuple and
> both of the following hold:
>
> 1. Each new unary tuple wrapper in `E2` is in a positive position.
> 2. Each new unary tuple wrapper in `E1` is in a negative position.
>
> Semantically,
>
> {{{#!hs
> unsafeCoerce :: (A -> B) -> A -> (# B #)
> =
> \f a -> let !fa = f a in (# fa #)
>
> unsafeCoerce :: ((# A #) -> B) -> A -> B
> =
> \f !a -> f a
> }}}
>
> Am I correct in this interpretation? If so, is this something the
> developers would be willing to commit to and document? The first version
> in particular (a new unary tuple wrapper in positive position in the
> result) would be very useful for reducing both source code and generated
> code size in libraries supporting both strict and lazy operations.

New description:

 It seems that it should be okay to `unsafeCoerce` between types that wrap
 certain things in unboxed unary tuples and ones that do not. For example,

 {{{#!hs
 unsafeCoerce :: (A -> B) -> A -> (# B #)
 unsafeCoerce :: ((# A #) -> B) -> A -> B
 }}}

 Generally, I believe `unsafeCoerce :: E1 -> E2` should be okay when the
 only differences are in what is wrapped in an unboxed unary tuple and both
 of the following hold:

 1. Each new unary tuple wrapper in `E2` is in a positive position.
 2. Each new unary tuple wrapper in `E1` is in a negative position.

 Semantically,

 {{{#!hs
 unsafeCoerce :: (A -> B) -> A -> (# B #)
 =
 \f a -> let !fa = f a in (# fa #)

 unsafeCoerce :: ((# A #) -> B) -> A -> B
 =
 \f !a -> f (# a #)
 }}}

 Am I correct in this interpretation? If so, is this something the
 developers would be willing to commit to and document? The first version
 in particular (a new unary tuple wrapper in positive position in the
 result) would be very useful for reducing both source code and generated
 code size in libraries supporting both strict and lazy operations.

--

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14806#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list