有没有办法将这两个不连贯的实例中的一个设置为首选? [英] Is there a way to set one of these two incoherent instances as preferred?
问题描述
class C ab其中
f: :b - > a - > b
除此之外,我还共存了两个实例。
第一个实例通过逐个应用可折叠集合中的元素来工作:
实例(可折叠m,C ab)=> C(ma)b其中
f = foldl f
第二个连接两个半群的元素:
instance(Monoid a)=> C aa其中
f = mappend
当然,一个类型可以是 Monoid
和 Foldable
(例如 String
)。
由于我假设 mappend
要针对案例进行优化(即,要定义一种联合手头可折叠集合的方式比传输元素更有效),我希望编译器尽可能选择第二个实例。如何表示或执行这种偏好?
确实,为了编译代码,我必须将这些实例指定为 incoherent $ c $这就是假的。正如我所看到的,
C aa
更具体,因为它只涉及一种变量类型。
您可以查看GitHub上的代码: kindaro / overlap 。
正如其他人所说,这是一个糟糕的主意。然而,我认为没有 IncoherentInstances
可能是可能的,只要你不需要其他实例。
instance { - #OVERLAPPABLE# - }
(可折叠m,C ab,q〜ma)
=> C q b其中
f = foldl f
实例{ - #OVERLAPPING# - }
Monoid a => C aa其中
f = mappend
为了更具可预测性的行为,您甚至可以重新使用它来使用一个类型家庭而不是重叠的实例,但它仍然是一个可怕的想法。这个类没有任何意义。
* Class Data.Monoid> f(12 :: Sum Int)(ZipList [1,2,3 :: Sum Int])
Sum {getSum = 18}
* Class Data.Monoid> f [1,2,3 :: Int] [12 :: Int]
[1,2,3,12]
I have this class at hand:
class C a b where
f :: b -> a -> b
Along with it, I have coexist two instances.
The first instance works by applying elements from a foldable collection one by one:
instance (Foldable m, C a b) => C (m a) b where
f = foldl f
The second conjoins two elements of a semigroup:
instance (Monoid a) => C a a where
f = mappend
Of course, a type can be an instance of both Monoid
and Foldable
(example be String
).
Since I presume mappend
to be optimized for the case (i.e. there to be defined a way of conjoining the foldable collections at hand more efficient than transferring elements one by one), I want the compiler to pick the second instance whenever possible. How can I denote or enforce such preferrence?
Indeed, to have the code compile I have to specify these instances as incoherent
which is right away false. As I see it, C a a
is more specific since it only involves one variable type.
You can review the code on GitHub: kindaro/overlap.
As others have said, this is a terrible idea. However, I think it's probably possible without IncoherentInstances
, as long as you don't want any other instances.
instance {-# OVERLAPPABLE #-}
(Foldable m, C a b, q ~ m a)
=> C q b where
f = foldl f
instance {-# OVERLAPPING #-}
Monoid a => C a a where
f = mappend
For more predictable behavior, you could even recast this to use a type family instead of overlapping instances, but it would still be a terrible idea. This class just doesn't make any sense.
*Class Data.Monoid> f (12 :: Sum Int) (ZipList [1,2,3 :: Sum Int])
Sum {getSum = 18}
*Class Data.Monoid> f [1,2,3:: Int] [12::Int]
[1,2,3,12]
这篇关于有没有办法将这两个不连贯的实例中的一个设置为首选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!