#1482: unsafeCoerce# doesn't always fully coerce
----------------------------------------+-----------------------------------
    Reporter:  [EMAIL PROTECTED]         |        Owner:         
        Type:  bug                      |       Status:  new    
    Priority:  normal                   |    Milestone:         
   Component:  Compiler (Type checker)  |      Version:  6.6.1  
    Severity:  normal                   |   Resolution:         
    Keywords:  unsafeCoerce#            |   Difficulty:  Unknown
          Os:  Linux                    |     Testcase:         
Architecture:  x86                      |  
----------------------------------------+-----------------------------------
Comment (by Isaac Dupree):

 LOL, I accidentally left out the ":t" in GHCi, and got (same result on x86
 6.6.1)
 {{{
 > unsafeCoerce# shows
 <interactive>: internal error: PAP object entered!
     (GHC version 6.6.1 for powerpc_unknown_linux)
     Please report this as a GHC bug:
 http://www.haskell.org/ghc/reportabug
 Aborted (core dumped)
 }}}
 What kind of showing is GHC trying to do on an object of type (forall b.
 b) anyway?

 Passing -fno-extended-default-rules didn't work for me to disable that in
 ghci, so I went to a .hs file:

 No, (shows::a -> String -> String) doesn't typecheck. (forall a. a ->
 String -> String) isn't a type of `shows`, only (forall a. Show a => a ->
 String -> String) is.

 {{{
 f :: forall a. a -> String -> String
 f = undefined
 e1 = ( unsafeCoerce# ) f
 }}}
 typechecks.  Type variables that could be anything at all, don't need to
 be instantiated.

 {{{
 e2 = (unsafeCoerce# :: (forall a. Show a => a -> String -> String) -> b)
 shows
 }}}
 typechecks. GHC can't infer a rank-2 type for unsafeCoerce, but you can
 give it one (`forall b. (forall a. Show a => a -> String -> String) -> b`
 is clearly a more-specific version of unsafeCoerce's type `forall a b. a
 -> b`).    This allows the ''polymorphic'' shows to be passed to
 unsafeCoerce, so that `shows` object can then be coerced as normal. (Rank-
 two types with typeclasses aren't nice, you always have to specify a new
 type signature when the set of type-classes is different...)

 Neither -fno-monomorphism-restriction nor defaulting are needed.

 Note that there is a difference between
 {{{(unsafeCoerce# :: (Integer -> String -> String) -> b) shows}}}
 (or whatever the type variable would default to, if not Integer)
 and
 {{{(unsafeCoerce# :: (forall a. Show a => a -> String -> String) -> b)
 shows}}}
 .
 Their representations are not the same; the second one can only be coerced
 back to the fully polymorphic version, and the first one can only be
 coerced back to the Integer version (well, probably if you wanted to pass
 _|_ for that parameter then you could also coerce the second one to have
 that parameter's type be anything you wanted, including polymorphic, as
 long as it wasn't qualified with a type-class constraint).

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1482>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to