haskell 结合约束?

bogh5gae  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(113)

我正在寻找一种方法来组合合并两个(或更多)约束,使Combine c1 c2 a意味着c1 ac2 a,反之亦然。当约束用作输入时,这可能很有用:

data HList constraint where
  Empty :: HList constraint
  (:*:) :: constraint a => a -> HList constraint -> HList constraint

字符串
其中shownegate可以应用于类型为HList (Combine Show Num)的hlist元素。
有了这些要求,type Combine c1 c2 a = (c1 a, c2 a)就做不到了,因为类型同义词必须饱和。我也试过将Combine声明为一个类,但不能暗示(Combine c1 c2 a) => c1 ac2 a

class (c1 a, c2 a) => Combine c1 c2 a
instance (c1 a, c2 a) => Combine c1 c2 a
instance Combine c1 c2 a => c1 a  -- error: Illegal head of an instance declaration
instance Combine c1 c2 a => c2 a  -- error: Illegal head of an instance declaration


我想知道这是否真的可能,或者有什么好的变通方法。

i2byvkas

i2byvkas1#

Combine c1 c2 a意味着c1 ac2 a这一事实已经包含在声明中

class (c1 a, c2 a) => Combine c1 c2 a

字符串
超类就是这样工作的!这是一个你以前肯定见过的特性。

-- Ord is declared "class Eq a => Ord a", therefore this works
eqOrd :: Ord a => a -> a -> Bool
eqOrd = (==) -- want Eq a, have Ord a, superclass constraint says this is enough


因此,您希望Combine做的所有事情都可以通过简单地编写

class (c1 a, c2 a) => Combine c1 c2 a
instance (c1 a, c2 a) => Combine c1 c2 a


例如,以下类型的

unzipCon :: HList (Combine c1 c2) -> (HList c1, HList c2)
unzipCon Empty      = (Empty, Empty)
unzipCon (x :*: xs) = (x :*: xs1, x :*: xs2)
  where (xs1, xs2) = unzipCon xs

相关问题