如何使用实例链解决重叠问题

问题描述 投票:0回答:1

我在 PureScript 版本 0.12.0-rc1 中遇到了

实例链接
的问题。按照我的理解,实例链允许显式指定实例解析顺序以避免实例定义重叠。

我想出了以下示例,但它无法编译:

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
purescript
1个回答
3
投票

即使有实例链,匹配仍然是在实例的头部完成的。当所选实例的任何约束失败时,不会出现“回溯”。

您的实例在头部完全重叠,因此您的第一个实例始终在第二个实例之前匹配,并且失败,因为没有

A
X
实例。

实例链允许您定义实例解析的显式顺序,而不依赖于例如名称的字母顺序等(因为直到 0.12.0 版本为止都是这样做的 - 请检查此处的第三段)。例如,您可以定义此重叠场景:

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
;-)

© www.soinside.com 2019 - 2024. All rights reserved.