[英]Map with Strings as Keys in Agda?
I'm having some trouble figuring out how to properly make a Map with String keys in Agda. 我在弄清楚如何正确地在Agda中使用String键制作Map时遇到了一些麻烦。 I've got the following: 我有以下几点:
import Data.AVL.IndexedMap
Var = String
data Type where -- ...
alwaysType : Var -> Set
alwaysType _ = Type
open Data.AVL.IndexedMap alwaysType (StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder)
This gives the error: 这给出了错误:
String != Σ String _Key_90 of type Set
when checking that the expression
StrictTotalOrder.isStrictTotalOrder strictTotalOrder has type
Relation.Binary.IsStrictTotalOrder .Agda.Builtin.Equality._≡_
__<__91
What is the proper way to open the Map module? 打开“地图”模块的正确方法是什么?
Note that the standard library's Data.AVL
has been updated to accept strict total orders not based on propositional equality. 请注意,标准库的Data.AVL
已更新,可以接受不基于命题相等性的严格总订单。
These days it is as simple as: 这些天,它很简单:
open import Data.String.Properties
open import Data.AVL strictTotalOrder
The Data.AVL.IndexedMap
module is for (finite) maps where there is a family of types for the keys and the values, and the value associated with a given key shares the index with the value. Data.AVL.IndexedMap
模块用于(有限)映射,其中键和值有一系列类型,并且与给定键关联的值与该值共享索引。
This is not what you want here, since you want all your keys to be String
s. 这不是您想要的,因为您希望所有键都是String
。 So just use Data.AVL
(ie the version with non-indexed keys): 因此,只需使用Data.AVL
(即具有未索引键的版本):
open import Data.String using (String)
open import Function using (const)
Key = String
postulate
Value : Set
open import Relation.Binary using (StrictTotalOrder)
open import Data.AVL (const Value) (StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder)
Unfortunately, this still doesn't typecheck: 不幸的是,这仍然没有类型检查:
.Relation.Binary.List.Pointwise.Rel
(StrictTotalOrder._≈_ .Data.Char.strictTotalOrder)
(Data.String.toList x) (Data.String.toList x₁)
!= x .Agda.Builtin.Equality.≡ x₁ of type Set
when checking that the expression
StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder
has type IsStrictTotalOrder .Agda.Builtin.Equality._≡_ __<__10
That's because Data.String.strictTotalOrder
uses pointwise equality (over the list of ℕ
values of the Char
s that make up the String
), and Data.AVL
requires propositional equality. 这是因为Data.String.strictTotalOrder
使用逐点相等(在组成String
的Char
的ℕ
值列表中),并且Data.AVL
需要命题相等。 So the exact same example would work with, eg, ℕ
keys: 因此,完全相同的示例将与ℕ
键一起工作:
open import Data.Nat using (ℕ)
open import Function using (const)
Key = ℕ
postulate
Value : Set
import Data.Nat.Properties
open import Relation.Binary using (StrictTotalOrder)
open import Data.AVL (const Value) (StrictTotalOrder.isStrictTotalOrder Data.Nat.Properties.strictTotalOrder)
So the next step needs to be to transform StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder
into something of type IsStrictTotalOrder (_≡_ {A = String}) _
. 因此,下一步需要将StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder
转换为IsStrictTotalOrder (_≡_ {A = String}) _
。 I'll leave that to someone else for now, but I'm happy to look into it later, when I have the time, if you can't get it working and noone else picks it up either. 我现在将其留给其他人,但是如果有时间,如果您无法使它正常工作,并且也没有其他人来找,我很乐意稍后进行调查。
EDITED TO ADD : Here's a (possibly horribly over-complicated) way of turning that StrictTotalOrder
for String
s from the standard lib into something that uses propositional equality: 编辑添加 :这是一种(可能非常复杂的)将StrictTotalOrder
for String
s从标准库转换为使用命题相等的方法:
open import Function using (const; _∘_; _on_)
open import Relation.Binary
open import Data.String
using (String; toList∘fromList; fromList∘toList)
renaming (toList to stringToList; fromList to stringFromList)
open import Relation.Binary.List.Pointwise as Pointwise
open import Relation.Binary.PropositionalEquality as P hiding (trans)
open import Data.Char.Base renaming (toNat to charToNat)
STO : StrictTotalOrder _ _ _
STO = record
{ Carrier = String
; _≈_ = _≡_
; _<_ = _<_
; isStrictTotalOrder = record
{ isEquivalence = P.isEquivalence
; trans = λ {x} {y} {z} → trans {x} {y} {z}
; compare = compare
}
}
where
open StrictTotalOrder Data.String.strictTotalOrder
renaming (isEquivalence to string-isEquivalence; compare to string-compare)
-- It feels like this should be defined somewhere in the
-- standard library, but I can't find it...
primCharToNat-inj : ∀ {x y} → primCharToNat x ≡ primCharToNat y → x ≡ y
primCharToNat-inj _ = trustMe
where
open import Relation.Binary.PropositionalEquality.TrustMe
open import Data.List
lem : ∀ {xs ys} → Pointwise.Rel (_≡_ on primCharToNat) xs ys → xs ≡ ys
lem [] = P.refl
lem {x ∷ xs} {y ∷ ys} (x∼y ∷ p) with primCharToNat-inj {x} {y} x∼y
lem {x ∷ xs} {_ ∷ ys} (x∼y ∷ p) | P.refl = cong _ (lem p)
≡-from-≈ : {s s′ : String} → s ≈ s′ → s ≡ s′
≡-from-≈ {s} {s′} p = begin
s ≡⟨ sym (fromList∘toList _) ⟩
stringFromList (stringToList s) ≡⟨ cong stringFromList (lem p) ⟩
stringFromList (stringToList s′) ≡⟨ fromList∘toList _ ⟩
s′ ∎
where
open P.≡-Reasoning
≈-from-≡ : {s s′ : String} → s ≡ s′ → s ≈ s′
≈-from-≡ {s} {_} refl = string-refl {s}
where
open IsEquivalence string-isEquivalence renaming (refl to string-refl) using ()
compare : (x y : String) → Tri (x < y) (x ≡ y) _
compare x y with string-compare x y
compare x y | tri< a ¬b ¬c = tri< a (¬b ∘ ≈-from-≡) ¬c
compare x y | tri≈ ¬a b ¬c = tri≈ ¬a (≡-from-≈ b) ¬c
compare x y | tri> ¬a ¬b c = tri> ¬a (¬b ∘ ≈-from-≡) c
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.