Scalaで等価証明を実装することは可能ですか?Scalaの従属型の等価プルーフ
Idrisによるタイプドリブン開発では、平等プルーフタイプの定義方法の例を示しています。
data (=): a -> b -> Type where
Refl : x = x
スカラ座にこれを変換するために私の最初の本能は、このようなものです。
sealed trait EqualityProof[A, B]
final case class EqualityProofToken[T](value: T) extends EqualityProof[value.type, value.type]
しかし、これは私が比較したい2つのオブジェクトが同じ正確なインスタンスであることをコンパイラに証明する必要があります。理想的には、これは異なるインスタンスである等しいオブジェクトに対して機能しますが、それはあまりにも多くを求めているかもしれません。これは、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インスタンスは、等しいことが証明されている長さのリストにジッピングとして同じ値を必要とする操作を実行するために使用することができます。
クラスタグやタイプタグがこの仕事をすることができるのだろうか...いずれにしても面白い質問です! – Alec
Scala *は依存する型の型を依存する型の型とパスに依存する型にします。ただし、エンコードは1:1ではなく、Idris/Agda/Coq/HOL/Guru/Epigramスタイルに依存する型をScalaにマップするだけではエンコードできません。私はあなたにどのように伝えるか十分に知識がありません。私の限られた理解から、「従属」部分はパス依存型と従属メソッド型を使用して符号化され、「証明」(または「検索」)部分は暗黙の解像度(必要な後戻りを提供する)を使用して符号化されます。 –
Idrisのことは、2つの値のシングルトンタイプが等しいことを証明しているので、2つの値が等しいというコンパイル時の証明がありますか?それとも、スカラーのdef equal [A、B](a:A、b:B)(暗黙のev:A =:= B)のように、 –