Get rid of fmapCoerce by ensuring our functors are representational#64
Get rid of fmapCoerce by ensuring our functors are representational#64shlevy wants to merge 1 commit into
Conversation
|
Nice but restrictive. Many |
|
@phadej Even when fully concrete? I.e. wouldn't When not concrete we can just require |
|
Indeed the universal instance here when specialized to |
|
Yes, this works foo :: (forall a b. Coercible a b => Coercible (f a) (f b), Applicative f) => f ()
foo = pure ()
bar :: IO ()
bar = foo
baz :: ReaderT r IO ()
baz = foo
{- Nope
qux :: (Applicative m) => ReaderT r m ()
qux = foo
-}
quux :: (Applicative m, forall a b. Coercible a b => Coercible (m a) (m b)) => ReaderT r m ()
quux = foo |
|
It works because |
|
Hmm I see. I don't fully understand why yet, but yes that's not working here to redefine ReaderT as a data type. Are there any real-world examples of such transformers? I'm used to always seeing them as newtypes, and all the ones I could find starting from the instance list of |
|
It's odd to me that newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
data ReaderTData r m a = ReaderTData { runReaderTData :: r -> m a }
data ReaderTIO r a = ReaderTIO { runReaderTIO :: r -> IO a }
representationalProxy :: (forall a b. Coercible a b => Coercible (f a) (f b)) => Proxy f
representationalProxy = Proxy
p1 :: Proxy (ReaderT r IO)
p1 = representationalProxy
p2 :: Proxy (ReaderTIO r)
p2 = representationalProxy
p3 :: Proxy (ReaderTData r IO)
p3 = representationalProxy |
|
That because Load into ghci and look for the roles in |
|
Right, but fully unsaturated |
For more information read through https://www.microsoft.com/en-us/research/uploads/prod/2018/05/coercible-JFP.pdf, in particular section 2.8 Supporting higher order polymorphism and 8.1 Roles for higher-order types TL;DR this needs support from GHC, higher order stuff just doesn't work. |
|
And to be clear about expectations: I won't merge this, nor work on other issues. GHC doesn't allow me to express what I want, and that was already identified in the original paper introducing roles. |
|
And FYI:
They should, but they aren't. There are fake functors too, e.g. https://hackage.haskell.org/package/bifunctors-5.5.14/docs/src/Data.Biapplicative.html#Mag and people will complain loudly if you suggest forcing EDIT: I tried to argue against, e.g. One :: a -> Mag a b bhas unboxed (equality) coercion, but One :: Coercible b c => a -> Mag a b cwould have unboxed one. So I guess you'd need to figure out how to tell GHC to have boxed coercions. So TL;DR, this issue has long history, and sorry that you had to re-learn it. But I'm somewhat frustrated going though arguments every other year. |
|
Sorry to bring this back up. I've opened https://gitlab.haskell.org/ghc/ghc/-/issues/22644, which I think would help with specifically the issue here without requiring the full solution of higher order roles or the |
Note that I didn't try to minimize the use of
RepresentationalMonad, since all real functors should be "representational" in this sense anyway, but perhaps some of these changes could be reverted back toMonad.