我一直在努力将Reflex更新为DMap 0.2,并遇到了翻译其中一个嵌入式仿函数的问题。
具体来说,它以前使用GADT来编码a -> [WeakSubscriber a]
关系,如下所示:
data FanSubscriberKey k a where
FanSubscriberKey :: k a -> FanSubscriberKey k [WeakSubscriber a]
然而,在最新版本的DMap中,您可以直接嵌入仿函数。我最初解除了上面的[]
,但意识到由于我有一个仿函数的仿函数,我有一个仿函数,并希望一起消除额外的数据。不幸的是,我不知道如何在不使用newtype的情况下描述上述映射。 newtype WeakSubscriberList a = WeakSubscriberList [WeakSubscriber a]
可以解决问题,但需要包装和展开新类型。
之前的研究指出,这被认为是一种类型级别的lambda,它通常是不允许的,但是这里的转换看起来很简单,以至于它是可能的,特别是因为我不想定义一个实例或类似的东西。
使用DMap 0.1,我们可以存储FanSubscriberKey k
,其值为[WeakSubscriber a]
DMap (FanSubscriberKey k)
,其密钥包含在FanSubscriberKey
构造函数中。在DMap 0.2中,如果我定义了上述newtype
,我可以同样地说DMap k WeakSubscriberList
并获得类似的结果,其中包含一个未包装的键但是包含在WeakSubscriberList
中的值。不过我想说的是DMap k [WeakSubscriber]
,但显然不会有效,因为[]
是善意的* -> *
而WeakSubscriber
是善意的* -> *
。如果有一个类型级别.
,那么[] '. WeakSubscriber
编译就可以完成这个技巧,但它同样不存在。我还尝试了类型别名,但type WeakSubscriberList a = [WeakSubscriber a]
要求在使用a
的地方指定WeakSubscriberList
。
答案 0 :(得分:0)
Data.Functor.Compose
是间接避免newtype
的简单方法。它仍然涉及newtype
,因为这是定义Compose
的方式,但不需要定义新的。{/ p>
上面的示例变为DMap k (Compose [] WeakSubscriber)
。