是否可以在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实例可用于执行需要相等值的操作,例如压缩到已证明相等的长度列表。
答案 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。 (免责声明:我是维护者之一)