依赖打字风格Scala中的平等证明

时间:2016-11-20 23:34:09

标签: scala type-systems dependent-type

是否可以在Scala中实现相等证明?

在“使用Idris进行类型驱动开发”一书中,它给出了如何定义等式证明类型的示例。

data (=): a -> b -> Type where
    Refl : x = x

我将此转换为Scala的第一直觉就是这样。

sealed trait EqualityProof[A, B]
final case class EqualityProofToken[T](value: T) extends EqualityProof[value.type, value.type]

然而,这需要我向编译器证明我想要比较的两个对象是完全相同的实例。理想情况下,这适用于不同实例的相等对象,但这可能要求太多。由于Scala允许可变数据,这只是一个无法避免的限制吗?有没有办法正确实现这个?如果没有,除了使用asInstanceOf来欺骗编译器(或限制使用asInstanceOf的方法)之外还有其他解决办法吗?

更新:似乎对问题的定义存在一些疑惑,因此我添加了更完整的Idris示例。

data EqNat : (num1 : Nat) -> (num2 : Nat) -> Type where
 Same : (num : Nat) -> EqNat num num

sameS : (k : Nat) -> (j : Nat) -> (eq : EqNat k j) -> EqNat (S k) (S j)
sameS k k (Same k) = Same (S k)

checkEqNat : (num1 : Nat) -> (num2 : Nat) -> Maybe (EqNat num1 num2)
checkEqNat Z Z = Just (Same 0)
checkEqNat Z (S k) = Nothing
checkEqNat (S k) Z = Nothing
checkEqNat (S k) (S j) = case checkEqNat k j of
                              Nothing => Nothing
                              Just eq => Just (sameS _ _ eq)

此时,EqNat实例可用于执行需要相等值的操作,例如压缩到已证明相等的长度列表。

1 个答案:

答案 0 :(得分:0)

Idris的简单翻译非常简单,您只需使用隐式提供编译时证明:

AudioToggle.setAudioMode(AudioToggle.EARPIECE).

它被放置在伴随对象中,因此当您需要隐含sealed trait Equality[A, B] case class Refl[A]() extends Equality[A, A] case object Equality { implicit def refl[B]: Equality[B, B] = Refl[B]() } 类型时,它将始终在范围内。

您可以在ohnosequences/cosas库中找到更具参与性的此类相等类型定义以及一些tests/examples。 (免责声明:我是维护者之一)