类型类实例的约束没有提到约束类型变量

时间:2017-03-03 18:48:30

标签: haskell typeclass

假设我们正在编写一个简单的bitset,它使用c类型的字段(想象Word)来表示类型a的不同值的存在:

data BitSet c a = BitSet c
            deriving (Eq, Ord, Data, Typeable, Generic, NFData)

isSet :: (Bits c, Enum a) => a -> BitSet c a -> Bool
isSet e (BitSet c) = testBit c $ fromEnum e
假设{p> aEnum,因此可以将其转换为与位索引对应的整数。

现在让我们尝试为Foldable编写BitSet c个实例,从以下开始:

instance FiniteBits c => Foldable (BitSet c) where
    foldr f b0 (BitSet c) = foldr f b0 list
        where (list :: [a]) = toEnum <$> filter (testBit c) [0..finiteBitSize c - 1]

但是这不起作用:它没有a应该满足Enum a的约束,我没有看到任何提供它的方法(我有一种直觉感觉到如果a未在实例声明中列出,那么从更理论的角度来看,它没有多大意义,但这可能是另一个故事。)

投票最多的答案here表明使用GADT可能有所帮助,但GADT有其自身的缺点:

  1. 需要使用独立派生,这对于数据和可输入性来说尤其难看,而且更糟糕的是,
  2. GADT似乎打破了这种类型的Generic派生。
  3. 还有其他方法可以在保留自动获取的通用实例的同时编写Foldable实例吗?

0 个答案:

没有答案