如何使用实例链解决重叠

How to use instance chain to solve overlapping

我一直在尝试下一个纯脚本版本 0.12.0-rc1。
我对如何使用新功能有疑问 'instance chain'.
在我的理解中,实例链提供了一个能够明确指定实例解析顺序的特性。这解决了避免实例定义重叠的问题。

所以我想它可能会起作用:

class A a
class B b
class C c where
  c :: c -> String

instance ca :: A a => C a where
  c = const "ca"
else
instance cb :: B b => C b where
  c = const "cb"

data X = X
instance bx :: B X

main :: forall eff. Eff (console :: CONSOLE | eff) Unit
main = logShow $ c X

但无法编译。

哪里不对? 或者实例链的用途是什么?

结果:

Error found:
in module Main
at src/Main.purs line 23, column 8 - line 23, column 20

  No type class instance was found for

Main.A X


while applying a function c
  of type C t0 => t0 -> String
  to argument X
while inferring the type of c X
in value declaration main

where t0 is an unknown type

即使使用实例链匹配仍然在实例头上完成。当所选实例的任何约束失败时,没有 "backtracking"。

你的实例在头上完全重叠,所以你的第一个实例总是在第二个之前匹配,但它失败了,因为 X 没有 A 个实例。

实例链允许您定义实例解析的显式排序,而不依赖于名称的字母顺序等(直到 0.12.0 版本 - please check the third paragraph here)。例如,您可以定义这个重叠场景:

class IsRecord a where
   isRecord :: a -> Boolean

instance a_isRecordRecord :: IsRecord (Record a) where
   isRecord _ = true

instance b_isRecordOther :: IsRecord a where
   isRecord _ = false

作为

instance isRecordRecord :: IsRecord (Record a) where
   isRecord _ = true
else instance isRecordOther :: IsRecord a where
   isRecord _ = false

我希望它能编译 - 我还没有 purs-0.12.0-rc ;-)