伊德里斯:隐藏的实现和暴露的平等

时间:2017-09-18 21:35:05

标签: idris

我们说我有一个模块。

module A
%default total
%access export

data D = A | B

Value1: D
Value1 = A

Value2: D
Value2 = A

由于Value1Value2的实现是隐藏的,我希望不可能在另一个模块中构建证明prf: Value1 = Value2,但事实上它是可能的:

module B
import A
%default total

prf: Value1 = Value2
prf = Refl

当我将Value2的定义更改为

Value2: D
Value2 = Value1

我收到了预期的错误。

现在,我通过扩展模块D并实现A来公开DecEq D的相等性。现在,在其他模块中运行时可以获得Value1 = Value2的实例:

main : IO ()
main = case decEq Value1 Value2 of
           Yes prf => putStrLn "Got instance of Value1 = Value2."
           No _ => putStrLn "This should not happen."

我希望使用decEq它也可以在类型检查时获得此证明的实例。我试过了

prf: Value1 = Value2
prf with (decEq Value1 Value2)
    | Yes p = p
    | No _ impossible

还有这个非常讨厌的解决方案:

%language TypeProviders
prfProvider : IO (Provider (Value1 = Value2))
prfProvider = do case decEq Value1 Value2 of
                     Yes p => pure (Provide p)
                     No _ => pure (Error "This should not happen.")
%provide (prf: Value1 = Value2) with prfProvider

两种解决方案都不起作用。

现在我的问题是:当Value1 = Value2定义Value2时,为什么我可以构建Value2 = A的实例?并且考虑到DecEq D的实现,有一种方法可以在编译时获取Value1 = Value2的实例,如果没有,为什么这样设计呢?

0 个答案:

没有答案