Allow ‘unsafe’ deriving strategy, deriving code with ‘unsafeCoerce’
This
newtype M m a = M (m a)
deriving newtype
Functor
produces something similar to
instance Functor m => Functor (M m) where
fmap :: forall a a'. (a -> a') -> (M m a -> M m a')
fmap = coerce (fmap @m @a @a')
but as wiki:Roles2 points out, this fails for methods such as join_:
class MonadJoin m where
join_ :: m (m a) -> m a
newtype M m a = M (m a)
deriving newtype
MonadJoin
-- Couldn't match representation of type ‘m (M m a)’ with that of ‘m (m a)’
I think the user should be given the option to respect the roles or not by supplying unsafe wiki:Commentary/Compiler/DerivingStrategies
newtype M m a = M (m a)
deriving unsafe newtype
MonadJoin
-- -( Produces `unsafeCoerce' instead of `coerce' )-
-- instance MonadJoin m => MonadJoin (M m) where
-- join_ :: forall a. M m (M m a) -> M m a
-- join_ = unsafeCoerce (join_ @m @a)
This lets us (newtype-) derive a host of instances that we currently can not: Traversable, Distributive (currently forbidden due to distribute), Trace, ProfunctorMonad / ProfunctorComonad, ...
It does not seem like lenses (FunctorWithIndex, FoldableWithIndex, TraversableWithIndex) work with this though
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.0.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |