scala - Scala 中的依赖打字风格相等证明

标签 scala type-systems dependent-type

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

在 Type Driven Development with 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 实例可用于执行需要相等值的操作,例如压缩到已证明相等的长度列表。

最佳答案

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

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]()
}

它被放置在伴随对象中,因此当您需要隐含的 Equality 时,它将始终在范围内。类型。

您可以在 ohnosequences/cosas 中找到此类相等类型的更复杂的定义。图书馆和一些 tests/examples . (免责声明:我是维护者之一)

关于scala - Scala 中的依赖打字风格相等证明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40710707/

相关文章:

haskell - 如何在与 Haskell 的 System-Fw 不匹配的类型系统中进行编程?

types - Coq 推理行为

haskell - 使用 GHC 进行依赖类型编程的运行时成本

equality - `subst`的分布率

scala - SBT 项目中的 "resources"文件夹有什么用?

scala - Scala Async 能做 Clojure 的 core.async 能做的所有事情吗?

scala - 可空列在尝试写入空值时导致 SlickException

Scala:接收服务器发送的事件

scala - scala 中类型不等式的类型约束

scala - 对于 Scala,类型删除有什么好处吗?