Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的依赖类型式等式证明_Scala_Type Systems_Dependent Type - Fatal编程技术网

Scala中的依赖类型式等式证明

Scala中的依赖类型式等式证明,scala,type-systems,dependent-type,Scala,Type Systems,Dependent Type,可以在Scala中实现等式证明吗 在Idris的“类型驱动开发”一书中,给出了如何定义平等证明类型的示例 data (=): a -> b -> Type where Refl : x = x 我把它转换成Scala的第一本能是这样的 密封式车顶[A,B] 最后一个案例类EqualityProofToken[T](值:T)扩展EqualityProof[value.type,value.type] 然而,这需要我向编译器证明我想要比较的两个对象是相同的实例。理想情况下,这

可以在Scala中实现等式证明吗

在Idris的“类型驱动开发”一书中,给出了如何定义平等证明类型的示例

data (=): a -> b -> Type where
    Refl : x = x
我把它转换成Scala的第一本能是这样的

密封式车顶[A,B]
最后一个案例类EqualityProofToken[T](值:T)扩展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]()
}
它被放置在伴随对象中,因此当您需要隐式的
相等
类型时,它将始终在范围内


您可以在库中找到此类相等类型的更复杂的定义,以及一些。(免责声明:我是维护人员之一)

我想知道类标记或类型标记是否能使这项工作正常。。。无论如何,这是个有趣的问题!Scala确实具有依赖方法类型和路径依赖类型形式的依赖类型。但是,编码不是1:1,您不能只将Idris/Agda/Coq/HOL/Guru/Epigram样式相关的类型映射到Scala,您必须对它们进行编码。我远没有足够的知识告诉你怎么做。根据我有限的理解,“依赖”部分是使用路径依赖类型和依赖方法类型编码的,“证明”(或“搜索”)部分是使用隐式解析(提供必要的回溯)编码的。我不太清楚:Idris的东西是否证明两个值的单例类型是相等的,这样就有了两个值相等的编译时证明?或者它仅仅证明了任何两种类型都是相等的,就像scala
defequal[A,B](A:A,B:B)(隐式ev:A=:=B)
?您应该能够在运行时证明值是相等的。我的理解是您返回一个可选的证明值,而不是布尔值。我认为您关于希望在运行时证明相等的评论令人困惑。您不必在运行时证明相等,只需检查它即可;Scala完全能够做到这一点,即使PHP也是如此!您想要做的是,您希望能够在编译时证明运行时值是相等的。以
zip
为例,您希望能够在编译时证明这两个列表在运行时具有相同的长度。这就是依赖类型提供给您的。据我所知,这证明了类型相等,而不是值相等。Idris示例完全能够证明值相等。在Scala中似乎没有任何方法可以做到这一点。我认为在类型/值方面存在一些混淆。今天晚些时候,我将扩展我的答案。您可以在Idris中证明值之间的相等性。这就是伊德里斯的特别之处@盛安安 是的,但据我所知,通过使用(依赖)类型,可以在编译时证明相等。如果(a==b),则在运行时证明相等。