Source code on Github
{-# OPTIONS --safe #-}
module Prelude.Lists.Count where

open import Prelude.Init; open SetAsType
open Nat.Ord
open Nat using (_≤_)
open import Prelude.Maybes
open import Prelude.Null
open import Prelude.Lists.Empty

private variable
  A B : Type 
  x : A; xs ys : List A

count :  {P : Pred A }  Decidable¹ P  List A  
count P? = length  filter P?

module _ {P : Pred A } (P? : Decidable¹ P) where
  count-step≤ : count P? xs  count P? (x  xs)
  count-step≤ {xs = xs} {x = x} with P? x
  ... | yes _ = Nat.≤-step Nat.≤-refl
  ... | no  _ = Nat.≤-refl

  count-++ :  xs {ys}  count P? (xs ++ ys)  count P? xs + count P? ys
  count-++ xs = trans (cong length $ L.filter-++ P? xs _)
                      (L.length-++ $ filter P? xs)

  length-count : count P? xs  length xs
  length-count {xs = xs} = L.length-filter P? xs

module _ (f : A  Maybe B) where
  countNothing countJust : List A  
  countNothing = count (is-nothing?  f)
  countJust    = count (is-just?  f)

  count-⊤⊥ : length xs  countJust xs + countNothing xs
  count-⊤⊥ {xs = []} = refl
  count-⊤⊥ {xs = x  xs}
    with IHcount-⊤⊥ {xs = xs}
    with f x
  ... | just _ = cong suc IH
  ... | nothing
    rewrite Nat.+-suc (countJust xs) (countNothing xs)
    = cong suc IH