我想进行实例声明,但自由类型变量不是最后一个变量。例如,我有一个类声明
class Poppable m where
tryPop :: m a -> Maybe (a, m a)
现在我想让 Q.PSQ(优先级队列)成为 Poppable 的实例。具体来说,我想要这样的东西:
instance (Ord p) => Poppable (\a -> Q.PSQ a p) where
tryPop = fmap (first Q.key) . Q.minView
然而,这不是合法的 Haskell 代码。如果 PSQ 的参数顺序交换,那么我就没有问题了:
instance (Ord p) => Poppable (Q.PSQ p) where
tryPop = fmap (first Q.key) . Q.minView
如何切换实例声明的参数顺序?
现在我可以用新类型包装 PSQ:
newtype PSQ'' a b = PSQ'' (Q.PSQ b a)
然而,这对我来说似乎很笨重,因为我必须不断地包装/打开它。有更容易的方法吗?
*
我尝试使用数据/类型系列,但都给出错误。
(1) 使用数据族声明:
data family PSQ' a b
data instance PSQ' a b = PSQ b a
instance (Ord p) => Poppable (PSQ' p) where
tryPop = fmap (first Q.key) . Q.minView
然而这给出了错误
Couldn't match type `Q.PSQ a p0' with `PSQ' p a'
即使它们可以通过设置 p=p0 来匹配。
(2) 类型族也不起作用。
type family PSQ' a b where
PSQ' b a = Q.PSQ a b
gives
Illegal type synonym family application in instance: PSQ' p