{-# OPTIONS --safe #-}
module Data.List.Properties where
open import Prelude
open import Algebra
open import Data.List
foldr-universal : ∀ (h : List B → A) f e
→ (h [] ≡ e)
→ (∀ x xs → h (x ∷ xs) ≡ f x (h xs))
→ ∀ xs → h xs ≡ foldr f e xs
foldr-universal h f e base step [] = base
foldr-universal h f e base step (x ∷ xs) =
step x xs ; cong (f x) (foldr-universal h f e base step xs)
foldr-id : (xs : List A) → xs ≡ foldr _∷_ [] xs
foldr-id = foldr-universal id _∷_ [] refl (λ _ _ → refl)
foldr-fusion : ∀ (f : C → A) {_⊕_ : B → C → C} {_⊗_ : B → A → A} e
→ (∀ x y → f (x ⊕ y) ≡ x ⊗ f y)
→ ∀ xs → f (foldr _⊕_ e xs) ≡ foldr _⊗_ (f e) xs
foldr-fusion h {f} {g} e fuse =
foldr-universal (h ∘ foldr f e) g (h e) refl (λ x xs → fuse x (foldr f e xs))
lmap : (A → B) → List A → List B
lmap f = foldr (_∷_ ∘ f) []
functorList : Functor {ℓ₁ = a} List
functorList .Functor.map = lmap
functorList .Functor.map-id = sym ∘′ foldr-id
functorList .Functor.map-comp f g = foldr-fusion (lmap f) [] λ x y → refl
all : (A → Bool) → List A → Bool
all p = foldr (_&&_ ∘ p) true
infixr 5 _∈_ _∉_
_∈_ : A → List A → Type _
x ∈ xs = ∃ i × (xs !! i ≡ x)
_∉_ : A → List A → Type _
x ∉ xs = ¬ (x ∈ xs)
there : ∀ (y : A) {x} {xs : List A} → x ∈ xs → x ∈ y ∷ xs
there _ (i , p) = fsuc i , p