Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ Additions to existing modules

* In `Data.List.Properties`:
```agda
length-catMaybes : length (catMaybes xs) ≤ length xs
applyUpTo-∷ʳ : applyUpTo f n ∷ʳ f n ≡ applyUpTo f (suc n)
applyDownFrom-∷ʳ : applyDownFrom (f ∘ suc) n ∷ʳ f 0 ≡ applyDownFrom f (suc n)
upTo-∷ʳ : upTo n ∷ʳ n ≡ upTo (suc n)
Expand Down
25 changes: 11 additions & 14 deletions src/Data/List/Base.agda
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,6 @@ map : (A → B) → List A → List B
map f [] = []
map f (x ∷ xs) = f x ∷ map f xs

mapMaybe : (A → Maybe B) → List A → List B
mapMaybe p [] = []
mapMaybe p (x ∷ xs) with p x
... | just y = y ∷ mapMaybe p xs
... | nothing = mapMaybe p xs

catMaybes : List (Maybe A) → List A
catMaybes = mapMaybe id

infixr 5 _++_

_++_ : List A → List A → List A
Expand Down Expand Up @@ -123,11 +114,11 @@ partitionSums : List (A ⊎ B) → List A × List B
partitionSums = partitionSumsWith id

merge : {R : Rel A ℓ} → B.Decidable R → List A → List A → List A
merge R? [] ys = ys
merge R? xs [] = xs
merge R? (x ∷ xs) (y ∷ ys) = if does (R? x y)
then x ∷ merge R? xs (y ∷ ys)
else y ∷ merge R? (x ∷ xs) ys
merge R? [] ys = ys
merge R? xs [] = xs
merge R? x∷xs@(x ∷ xs) y∷ys@(y ∷ ys) = if does (R? x y)
then x ∷ merge R? xs y∷ys
else y ∷ merge R? x∷xs ys

------------------------------------------------------------------------
-- Operations for reducing lists
Expand All @@ -149,6 +140,12 @@ concatMap f = concat ∘ map f
ap : List (A → B) → List A → List B
ap fs as = concatMap (flip map as) fs

catMaybes : List (Maybe A) → List A
catMaybes = foldr (maybe′ _∷_ id) []

mapMaybe : (A → Maybe B) → List A → List B
mapMaybe p = catMaybes ∘ map p

null : List A → Bool
null [] = true
null (x ∷ xs) = false
Expand Down
70 changes: 37 additions & 33 deletions src/Data/List/Properties.agda
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ open import Data.List.Base as List
open import Data.List.Membership.Propositional using (_∈_)
open import Data.List.Relation.Unary.All using (All; []; _∷_)
open import Data.List.Relation.Unary.Any using (Any; here; there)
open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)
open import Data.Maybe.Base as Maybe using (Maybe; just; nothing; maybe)
open import Data.Nat.Base
open import Data.Nat.Divisibility using (_∣_; divides; ∣n⇒∣m*n)
open import Data.Nat.Properties
Expand Down Expand Up @@ -56,23 +56,23 @@ private
C : Set c
D : Set d
E : Set e
x y z w : A
xs ys zs ws : List A

------------------------------------------------------------------------
-- _∷_

module _ {x y : A} {xs ys : List A} where
∷-injective : x ∷ xs ≡ y List.∷ ys → x ≡ y × xs ≡ ys
∷-injective refl = refl , refl

∷-injective : x ∷ xs ≡ y List.∷ ys → x ≡ y × xs ≡ ys
∷-injective refl = (refl , refl)
∷-injectiveˡ : x ∷ xs ≡ y List.∷ ys → x ≡ y
∷-injectiveˡ refl = refl

∷-injectiveˡ : x ∷ xs ≡ y List.∷ ys → xy
∷-injectiveˡ refl = refl
∷-injectiveʳ : x ∷ xs ≡ y List.∷ ys → xsys
∷-injectiveʳ refl = refl

∷-injectiveʳ : x ∷ xs ≡ y List.∷ ys → xs ≡ ys
∷-injectiveʳ refl = refl

∷-dec : Dec (x ≡ y) → Dec (xs ≡ ys) → Dec (x List.∷ xs ≡ y ∷ ys)
∷-dec x≟y xs≟ys = Decidable.map′ (uncurry (cong₂ _∷_)) ∷-injective (x≟y ×-dec xs≟ys)
∷-dec : Dec (x ≡ y) → Dec (xs ≡ ys) → Dec (x ∷ xs ≡ y List.∷ ys)
∷-dec x≟y xs≟ys = Decidable.map′ (uncurry (cong₂ _∷_)) ∷-injective (x≟y ×-dec xs≟ys)

≡-dec : DecidableEquality A → DecidableEquality (List A)
≡-dec _≟_ [] [] = yes refl
Expand Down Expand Up @@ -122,28 +122,34 @@ map-injective finj {x ∷ xs} {y ∷ ys} eq =
------------------------------------------------------------------------
-- mapMaybe

length-catMaybes : ∀ xs → length (catMaybes {A = A} xs) ≤ length xs
length-catMaybes [] = ≤-refl
length-catMaybes (just x ∷ xs) = s≤s (length-catMaybes xs)
length-catMaybes (nothing ∷ xs) = m≤n⇒m≤1+n (length-catMaybes xs)

mapMaybe-just : (xs : List A) → mapMaybe just xs ≡ xs
mapMaybe-just [] = refl
mapMaybe-just (x ∷ xs) = cong (x ∷_) (mapMaybe-just xs)

mapMaybe-nothing : (xs : List A) →
mapMaybe {B = A} (λ _ → nothing) xs ≡ []
mapMaybe {B = B} (λ _ → nothing) xs ≡ []
mapMaybe-nothing [] = refl
mapMaybe-nothing (x ∷ xs) = mapMaybe-nothing xs

module _ (f : A → Maybe B) where

mapMaybe-concatMap : mapMaybe f ≗ concatMap (fromMaybe ∘ f)
mapMaybe-concatMap [] = refl
mapMaybe-concatMap [] = refl
mapMaybe-concatMap (x ∷ xs) with ih ← mapMaybe-concatMap xs | f x
... | just y = cong (y ∷_) ih
... | nothing = ih

length-mapMaybe : ∀ xs → length (mapMaybe f xs) ≤ length xs
length-mapMaybe [] = z≤n
length-mapMaybe (x ∷ xs) with ih ← length-mapMaybe xs | f x
... | just y = s≤s ih
... | nothing = m≤n⇒m≤1+n ih
length-mapMaybe xs = ≤-begin
length (mapMaybe f xs) ≤⟨ length-catMaybes (map f xs) ⟩
length (map f xs) ≤⟨ ≤-reflexive (length-map f xs) ⟩
length xs ≤-∎
where open ≤-Reasoning renaming (begin_ to ≤-begin_; _∎ to _≤-∎)

------------------------------------------------------------------------
-- _++_
Expand Down Expand Up @@ -175,14 +181,14 @@ module _ {A : Set a} where
++-identityʳ-unique : ∀ (xs : List A) {ys} → xs ≡ xs ++ ys → ys ≡ []
++-identityʳ-unique [] refl = refl
++-identityʳ-unique (x ∷ xs) eq =
++-identityʳ-unique xs (proj₂ (∷-injective eq))
++-identityʳ-unique xs (∷-injectiveʳ eq)

++-identityˡ-unique : ∀ {xs} (ys : List A) → xs ≡ ys ++ xs → ys ≡ []
++-identityˡ-unique [] _ = refl
++-identityˡ-unique {xs = x ∷ xs} (y ∷ ys) eq
with ++-identityˡ-unique (ys ++ [ x ]) (begin
xs ≡⟨ proj₂ (∷-injective eq)
ys ++ x ∷ xs ≡⟨ sym (++-assoc ys [ x ] xs) ⟩
xs ≡⟨ ∷-injectiveʳ eq ⟩
ys ++ x ∷ xs ≡⟨ ++-assoc ys [ x ] xs
(ys ++ [ x ]) ++ xs ∎)
++-identityˡ-unique {xs = x ∷ xs} (y ∷ [] ) eq | ()
++-identityˡ-unique {xs = x ∷ xs} (y ∷ _ ∷ _) eq | ()
Expand Down Expand Up @@ -1215,22 +1221,20 @@ reverse-downFrom = reverse-applyDownFrom id
------------------------------------------------------------------------
-- _∷ʳ_

module _ {x y : A} where

∷ʳ-injective : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys × x ≡ y
∷ʳ-injective [] [] refl = (refl , refl)
∷ʳ-injective (x ∷ xs) (y ∷ ys) eq with refl , eq′ ← ∷-injective eq
= Product.map (cong (x ∷_)) id (∷ʳ-injective xs ys eq′)
∷ʳ-injective [] (_ ∷ _ ∷ _) ()
∷ʳ-injective (_ ∷ _ ∷ _) [] ()
∷ʳ-injective : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys × x ≡ y
∷ʳ-injective [] [] refl = refl , refl
∷ʳ-injective (x ∷ xs) (y ∷ ys) eq with refl , eq′ ← ∷-injective eq
= Product.map (cong (x ∷_)) id (∷ʳ-injective xs ys eq′)
∷ʳ-injective [] (_ ∷ _ ∷ _) ()
∷ʳ-injective (_ ∷ _ ∷ _) [] ()

∷ʳ-injectiveˡ : ∀ (xs ys : List A) → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys
∷ʳ-injectiveˡ xs ys eq = proj₁ (∷ʳ-injective xs ys eq)
∷ʳ-injectiveˡ : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys
∷ʳ-injectiveˡ xs ys eq = proj₁ (∷ʳ-injective xs ys eq)

∷ʳ-injectiveʳ : ∀ (xs ys : List A) → xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ y
∷ʳ-injectiveʳ xs ys eq = proj₂ (∷ʳ-injective xs ys eq)
∷ʳ-injectiveʳ : ∀ xs ys → xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ y
∷ʳ-injectiveʳ xs ys eq = proj₂ (∷ʳ-injective xs ys eq)

∷ʳ-++ : ∀ (xs : List A) (a : A) (ys : List A) → xs ∷ʳ a ++ ys ≡ xs ++ a ∷ ys
∷ʳ-++ : ∀ xs (a : A) ys → xs ∷ʳ a ++ ys ≡ xs ++ a ∷ ys
∷ʳ-++ xs a ys = ++-assoc xs [ a ] ys


Expand Down