{-# OPTIONS --without-K --safe #-}
module Data.Sum where
open import Level
open import Function
infixr 3 _⊎_
data _⊎_ (A : Type a) (B : Type b) : Type (a ℓ⊔ b) where
inl : A → A ⊎ B
inr : B → A ⊎ B
either : ∀ {ℓ} {C : A ⊎ B → Type ℓ} → ((a : A) → C (inl a)) → ((b : B) → C (inr b))
→ (x : A ⊎ B) → C x
either f _ (inl x) = f x
either _ g (inr y) = g y
either′ : (A → C) → (B → C) → (A ⊎ B) → C
either′ = either
_▿_ : (A → C) → (B → C) → A ⊎ B → C
(f ▿ g) (inl x) = f x
(f ▿ g) (inr x) = g x
map-⊎ : ∀ {a₁ a₂ b₁ b₂} {A₁ : Type a₁} {A₂ : Type a₂} {B₁ : Type b₁} {B₂ : Type b₂} →
(A₁ → A₂) →
(B₁ → B₂) →
(A₁ ⊎ B₁) →
(A₂ ⊎ B₂)
map-⊎ f g = either (inl ∘ f) (inr ∘ g)
mapˡ : (A → B) → A ⊎ C → B ⊎ C
mapˡ f = map-⊎ f id
mapʳ : (A → B) → C ⊎ A → C ⊎ B
mapʳ = map-⊎ id
open import Path
inl-inj : Injective (inl {A = A} {B = B})
inl-inj {y = y} = cong (either′ id (const y))
inr-inj : Injective (inr {A = A} {B = B})
inr-inj {x = x} = cong (either′ (const x) id)
open import Data.Bool
open import Data.Bool.Properties
is-l : A ⊎ B → Bool
is-l = either′ (const true) (const false)
inr≢inl : {x : A} {y : B} → inr x ≢ inl y
inr≢inl = false≢true ∘ cong is-l
inl≢inr : {x : A} {y : B} → inl x ≢ inr y
inl≢inr = true≢false ∘ cong is-l
open import Decidable
open import Data.Sigma
Discrete-⊎ : Discrete A → Discrete B → Discrete (A ⊎ B)
Discrete-⊎ lhs _ (inl x) (inl y) = iff-dec (cong inl , inl-inj) (lhs x y)
Discrete-⊎ _ _ (inl x) (inr x₁) = no inl≢inr
Discrete-⊎ _ _ (inr x) (inl x₁) = no inr≢inl
Discrete-⊎ _ rhs (inr x) (inr y) = iff-dec (cong inr , inr-inj) (rhs x y)