簡體   English   中英

agda返回列表的偶數索引

[英]agda return the even number index of the list

代碼是:

filter-pos : {A : Set} → 𝕃 A → (ℕ → 𝔹) → 𝕃 A 
filter-pos = {!!}

filter-pos-test : filter-pos ('a' :: 'b' :: 'c' :: 'd' :: 'e' :: 'f' :: []) is-even ≡ 'a' :: 'c' :: 'e' :: []
filter-pos-test = refl

我的想法是使用nth輸出nth索引,使用map函數使它們成為一個列表,如果它是偶數n ,它將返回。 但是,這不能正常工作。

有人可以讓我知道如何解決這個問題嗎? 我認為編寫幫助功能來解決問題會有所幫助。

我將使用標准庫。

一種愚蠢的解決方案是使用元素索引壓縮列表,使用常規filter ,然后刪除索引。 例如

'a' :: 'b' :: 'c' :: 'd' :: 'e' :: 'f' :: []

('a', 0) :: ('b', 1) :: ('c', 2) :: ('d', 3) :: ('e', 4) :: ('f', 5) :: []

filter (is-even ∘ snd)返回

('a', 0) :: ('c', 2) :: ('e', 4) :: []

並在中map fst結果

'a' :: 'c' :: 'e' :: []

一個更自然的解決方案是遍歷列表並在每個遞歸調用上增加一個計數器:

filter-pos : {A : Set} → List A → (ℕ → Bool) → List A 
filter-pos {A} xs p = go 0 xs where
  go : ℕ -> List A -> List A
  go i  []      = []
  go i (x ∷ xs) = if p i then x ∷ r else r where
    r = go (suc i) xs

在這里, i是元素的索引。 但是現在,每當需要證明有關filter-pos ,您都需要證明有關go的引理,因為它go完成實際的工作,而filter-pos只是它的包裝。 慣用的解決方案如下所示:

filter-pos : {A : Set} → List A → (ℕ → Bool) → List A 
filter-pos  []      p = []
filter-pos (x ∷ xs) p = if p 0 then x ∷ r else r where
  r = filter-pos xs (p ∘ suc)

在這里,我們沒有調整計數器,而是調整了謂詞,並用suc 因此,在第一個元素上,我們檢查p 0是否為真,在第二個元素上,我們檢查(p ∘ suc) 0 (立即變為p 1 )是否為真,在第三個元素上,我們檢查(p ∘ suc ∘ suc) 0 (立即減少到p 2 )為真,依此類推。 即,這與使用計數器的解決方案相同,但是僅使用一個功能。

最后一個版本也可以調整與工作Fin代替

filter-pos-fin : {A : Set} → (xs : List A) → (Fin (length xs) → Bool) → List A 
filter-pos-fin  []      p = []
filter-pos-fin (x ∷ xs) p = if p zero then x ∷ r else r where
  r = filter-pos-fin xs (p ∘ suc)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM