Martin Escardo, Paulo Oliva, 2024 Non-empty list monad. \begin{code} {-# OPTIONS --safe --without-K #-} open import MLTT.Spartan hiding (J) module Games.NonEmptyListOriginal where open import Games.Monad data neList (X : Type) : Type where [_] : X → neList X _::_ : X → neList X → neList X infixr 3 _::_ infixr 2 _++_ _++_ : {X : Type} → neList X → neList X → neList X [ x ] ++ ys = x :: ys (x :: xs) ++ ys = x :: (xs ++ ys) assoc-++ : {X : Type} (xs ys zs : neList X) → (xs ++ ys) ++ zs = xs ++ (ys ++ zs) assoc-++ [ x ] ys zs = refl assoc-++ (x :: xs) ys zs = ap (x ::_) (assoc-++ xs ys zs) 𝕃⁺ : Monad 𝕃⁺ = record { functor = neList ; η = [_] ; ext = ext' ; ext-η = ext'-η ; unit = λ f x → refl ; assoc = assoc' } where ext' : {X Y : Type} → (X → neList Y) → neList X → neList Y ext' f [ x ] = f x ext' f (x :: xs) = f x ++ ext' f xs ext'-++ : {Y Z : Type} (g : Y → neList Z) (xs ys : neList Y) → ext' g xs ++ ext' g ys = ext' g (xs ++ ys) ext'-++ g [ x ] ys = refl ext'-++ g (x :: xs) ys = ext' g (x :: xs) ++ ext' g ys =⟨ refl ⟩ (g x ++ ext' g xs) ++ ext' g ys =⟨ assoc-++ (g x) (ext' g xs) (ext' g ys) ⟩ g x ++ (ext' g xs ++ ext' g ys) =⟨ ap (g x ++_) (ext'-++ g xs ys) ⟩ g x ++ ext' g (xs ++ ys) =⟨ refl ⟩ ext' g (x :: xs ++ ys) ∎ ext'-η : {X : Type} → ext' [_] ∼ 𝑖𝑑 (neList X) ext'-η [ x ] = refl ext'-η (x :: xs) = ap (x ::_) (ext'-η xs) assoc' : {X Y Z : Type} (g : Y → neList Z) (f : X → neList Y) (xs : neList X) → ext' (λ - → ext' g (f -)) xs = ext' g (ext' f xs) assoc' g f [ x ] = refl assoc' g f (x :: xs) = ext' (λ - → ext' g (f -)) (x :: xs) =⟨ refl ⟩ ext' g (f x) ++ ext' (λ - → ext' g (f -)) xs =⟨ ap (ext' g (f x) ++_) (assoc' g f xs) ⟩ ext' g (f x) ++ ext' g (ext' f xs) =⟨ ext'-++ g (f x) (ext' f xs) ⟩ ext' g (f x ++ ext' f xs) =⟨ refl ⟩ ext' g (ext' f (x :: xs)) ∎ module neList-definitions where _⊗ᴸ⁺_ : {X : Type} {Y : X → Type} → neList X → ((x : X) → neList (Y x)) → neList (Σ x ꞉ X , Y x) _⊗ᴸ⁺_ = _⊗_ 𝕃⁺ ηᴸ⁺ : {X : Type} → X → neList X ηᴸ⁺ = η 𝕃⁺ extᴸ⁺ : {X Y : Type} → (X → neList Y) → neList X → neList Y extᴸ⁺ = ext 𝕃⁺ mapᴸ⁺ : {X Y : Type} → (X → Y) → neList X → neList Y mapᴸ⁺ = map 𝕃⁺ \end{code}