我正在为部分类半身像编写接口,如下所示:
infixr 9 <>
interface PartialMonoid (m : Type) where
compatible : m -> m -> Bool
(<>) : (a : m) -> (b : m) -> {auto p : compatible a b = True} -> m
以简单的实现作为概念验证:
data MyPos : Type where
A : MyPos
B : MyPos
C : MyPos
op : (a : MyPos) -> (b : MyPos) -> Bool
op A A = True
op B B = True
op C C = True
op A B = True
op B A = True
op A C = True
op C A = True
op x y = False
PartialMonoid MyPos where
compatible = op
A <> A = A
B <> B = B
C <> C = C
A <> B = B
A <> C = C
C <> A = C
B <> A = B
(<>) B C {p = Refl} impossible
(<>) C B {p = Refl} impossible
每当我尝试在REPL中评估类似A <> B
之类的内容时,都会得到预期的行为。但是,当评估(例如)(A <> B) <> A
而不是预期的A
时,我得到
Type mismatch between
MyPos (Type of A)
and
compatible A B = True (Expected type)
这让我感到困惑,因为如果在REPL中,我会这样做:
:let x = (A <> B)
x <> A
然后我得到了预期的B
。
这是怎么回事?并且,如果这是我的代码中的问题而不是错误,是否有任何方法可以使这种带有隐式“ compatibility”参数的部分monoid操作按预期在Idris中工作? (即,在您尝试合并两个不兼容的元素之前,一切都会顺利进行,例如B <> C
会导致类型错误)