I have been playing around with updating Reflex to DMap 0.2 and ran into an issue translating one of the embedded functors.
Specifically it previously used a GADT to encode an a -> [WeakSubscriber a]
relationship like so:
data FanSubscriberKey k a where
FanSubscriberKey :: k a -> FanSubscriberKey k [WeakSubscriber a]
However in the newest version of DMap you can just embed a functor directly. I initially lifted the []
out of the above but realized that since I had a functor of a functor, I had a functor and wanted to eliminate the extra data all together. Unfortunately I cannot figure out a way to describe the above mapping without using a newtype. newtype WeakSubscriberList a = WeakSubscriberList [WeakSubscriber a]
would solve the problem but would require wrapping and unwrapping the newtype.
Previous research points to this being considered a type-level lambda which is usually disallowed but the transformation here seemed simple enough that it could be possible, especially since I am not looking to define an instance or anything like that.
Using DMap 0.1 we can store a FanSubscriberKey k
and have its value be a [WeakSubscriber a]
in a DMap (FanSubscriberKey k)
with its key being wrapped in the FanSubscriberKey
constructor. In DMap 0.2 if I defined the above newtype
I could similarly say DMap k WeakSubscriberList
and get a similar result having an unwrapped key but a value wrapped in WeakSubscriberList
. However what I would like to say is DMap k [WeakSubscriber]
but that obviously won't work since []
is kind * -> *
and WeakSubscriber
is kind * -> *
. If there were a type level .
such that [] '. WeakSubscriber
compiled that would do the trick but it similarly does not exist. I also tried a type alias but type WeakSubscriberList a = [WeakSubscriber a]
requires that a
be specified wherever WeakSubscriberList
is used.
Data.Functor.Compose
is a straightforward way of indirectly avoiding the newtype
. It still involves a newtype
, since that is how Compose
is defined, but a new one doesn't need to be defined.
The example above becomes DMap k (Compose [] WeakSubscriber)
.