在尝试使用 Numeric prelude 定义一些数学对象时,我遇到了一个问题。Additive 类型类定义了一个实例
instance Additive.C v => Additive.C [v]
我读到“如果 v 是加法,[v] 也是”(显然我在这里错了)。它的实现类似于
(+) x y = map (\(a,b) -> a + b) $ zip x y
所以 [1,2,3] + [4,5,6] = [5,7,9] 这对我想做的事情毫无用处。我以为我不会有问题,因为我的 v 类型不是 Additive。不幸的是,我仍然遇到了一个重叠的实例错误,我发现这非常令人困惑。我做了一些阅读,现在我明白了,出于某种原因,Haskell 忽略了“=>”位之前的所有内容,所以我应该将默认实例阅读为“任何列表在默认实例的意义上都可能是附加的”。尽管这个扩展有“危险”的名声,但我尝试过使用 OverlappingInstances,但即使这样似乎也无济于事。
这是我的测试用例。
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses,FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-} --This doesn't seem to help
import NumericPrelude
import qualified Algebra.Additive as Additive
data Test = Red | Green | Blue deriving Show
instance Additive.C [Test] where
zero = undefined
(+) = undefined
negate = undefined
test = [Red] + [Green] + [Blue]
产生错误(更新:这似乎只发生在旧版本的 GHC 中。版本 7.2.2 似乎接受它):
Overlapping instances for Additive.C [Test]
arising from a use of `+'
Matching instances:
instance Additive.C v => Additive.C [v]
-- Defined in Algebra.Additive
instance [overlap ok] Additive.C [Test]
-- Defined at Testcase.hs:10:10-26
In the first argument of `(+)', namely `[Red] + [Green]'
In the expression: [Red] + [Green] + [Blue]
In an equation for `test': test = [Red] + [Green] + [Blue]
这是否意味着我不能使用列表,因为我不想默认 Additive 实例?我真正想做的是告诉 ghc 忘记那个默认实例,这可能吗?如果没有,除了删除列表之外,我不确定从这里去哪里。