
#14070: Allow ‘unsafe’ deriving strategy, deriving code with ‘unsafeCoerce’ -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: | QuantifiedContexts, deriving 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 RyanGlScott): GHC can "coerce" that just fine (roles notwithstanding) if you do it the way `GeneralizedNewtypeDeriving` generates code (pretend I'm using `coerce` instead of `unsafeCoerce`): {{{#!hs {-# LANGUAGE ImpredicativeTypes #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} import Unsafe.Coerce type Lens s a = forall f. Functor f => (a -> f a) -> (s -> f s) class X f where x :: Lens (f a) a newtype WrappedX f a = WrapX (f a) instance X t => X (WrappedX t) where x = unsafeCoerce @(forall a. Lens (t a) a) @(forall a. Lens (WrappedX t a) a) x }}} I put "coerce" in quotes because we're not actually coercing the `f`. Rather, the two occurrences of `f` tucked underneath the `Lens`es get unified. But you were writing this instance in a somewhat unorthodox way where you manually applied `@t` and `@a` to `x`, but neglected `f` (`f` isn't in scope the way you wrote it, but it's hiding underneath the `Lens`). Because of this, GHC was unable to conclude that the `f` in `x'` and the `f` in the instance signature were the same. Happily, writing instances the way `GeneralizedNewtypeDeriving` does (by visibly applying the full type signatures to `coerce`) doesn't suffer from this problem. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14070#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler