# The maybe modality

```agda
module foundation.maybe where
```

<details><summary>Imports</summary>

```agda
open import foundation.coproduct-types
open import foundation.decidable-types
open import foundation.dependent-pair-types
open import foundation.equality-coproduct-types
open import foundation.type-arithmetic-empty-type
open import foundation.unit-type
open import foundation.universe-levels

open import foundation-core.embeddings
open import foundation-core.empty-types
open import foundation-core.equivalences
open import foundation-core.identity-types
open import foundation-core.injective-maps
open import foundation-core.negation
```

</details>

## Idea

The maybe modality is an operation on types that adds one point. This is used,
for example, to define partial functions, where a partial function `f : X ⇀ Y`
is a map `f : X → Maybe Y`.

## Definitions

### The Maybe modality

```agda
Maybe : {l : Level}  UU l  UU l
Maybe X = X + unit

data Maybe' {l} (X : UU l) : UU l where
  unit-Maybe' : X  Maybe' X
  exception-Maybe' : Maybe' X

{-# BUILTIN MAYBE Maybe' #-}

unit-Maybe : {l : Level} {X : UU l}  X  Maybe X
unit-Maybe = inl

exception-Maybe : {l : Level} {X : UU l}  Maybe X
exception-Maybe {l} {X} = inr star
```

### The predicate of being an exception

```agda
is-exception-Maybe : {l : Level} {X : UU l}  Maybe X  UU l
is-exception-Maybe {l} {X} x = (x  exception-Maybe)

is-not-exception-Maybe : {l : Level} {X : UU l}  Maybe X  UU l
is-not-exception-Maybe x = ¬ (is-exception-Maybe x)
```

### The predicate of being a value

```agda
is-value-Maybe : {l : Level} {X : UU l}  Maybe X  UU l
is-value-Maybe {l} {X} x = Σ X  y  inl y  x)

value-is-value-Maybe :
  {l : Level} {X : UU l} (x : Maybe X)  is-value-Maybe x  X
value-is-value-Maybe x = pr1

eq-is-value-Maybe :
  {l : Level} {X : UU l} (x : Maybe X) (H : is-value-Maybe x) 
  inl (value-is-value-Maybe x H)  x
eq-is-value-Maybe x H = pr2 H
```

### Maybe structure on a type

```agda
maybe-structure : {l1 : Level} (X : UU l1)  UU (lsuc l1)
maybe-structure {l1} X = Σ (UU l1)  Y  Maybe Y  X)
```

## Properties

### The unit of Maybe is an embedding

```agda
abstract
  is-emb-unit-Maybe : {l : Level} {X : UU l}  is-emb (unit-Maybe {X = X})
  is-emb-unit-Maybe {l} {X} = is-emb-inl X unit

emb-unit-Maybe : {l : Level} (X : UU l)  X  Maybe X
pr1 (emb-unit-Maybe X) = unit-Maybe
pr2 (emb-unit-Maybe X) = is-emb-unit-Maybe

abstract
  is-injective-unit-Maybe :
    {l : Level} {X : UU l}  is-injective (unit-Maybe {X = X})
  is-injective-unit-Maybe = is-injective-inl
```

### Being an exception is decidable

```agda
is-decidable-is-exception-Maybe :
  {l : Level} {X : UU l} (x : Maybe X)  is-decidable (is-exception-Maybe x)
is-decidable-is-exception-Maybe {l} {X} (inl x) =
  inr  p  ex-falso (is-empty-eq-coproduct-inl-inr x star p))
is-decidable-is-exception-Maybe (inr star) = inl refl

is-decidable-is-not-exception-Maybe :
  {l : Level} {X : UU l} (x : Maybe X)  is-decidable (is-not-exception-Maybe x)
is-decidable-is-not-exception-Maybe x =
  is-decidable-neg (is-decidable-is-exception-Maybe x)
```

### The values of the unit of the Maybe modality are not exceptions

```agda
abstract
  is-not-exception-unit-Maybe :
    {l : Level} {X : UU l} (x : X)  is-not-exception-Maybe (unit-Maybe x)
  is-not-exception-unit-Maybe {l} {X} x ()
```

### For any element of type `Maybe X` we can decide whether it is a value or an exception

```agda
decide-Maybe :
  {l : Level} {X : UU l} (x : Maybe X)  is-value-Maybe x + is-exception-Maybe x
decide-Maybe (inl x) = inl (pair x refl)
decide-Maybe (inr star) = inr refl
```

### Values are not exceptions

```agda
abstract
  is-not-exception-is-value-Maybe :
    {l1 : Level} {X : UU l1} (x : Maybe X) 
    is-value-Maybe x  is-not-exception-Maybe x
  is-not-exception-is-value-Maybe {l1} {X} .(inl x) (pair x refl) =
    is-not-exception-unit-Maybe x
```

### If a point is not an exception, then it is a value

```agda
is-value-is-not-exception-Maybe :
  {l1 : Level} {X : UU l1} (x : Maybe X) 
  is-not-exception-Maybe x  is-value-Maybe x
is-value-is-not-exception-Maybe x H =
  map-right-unit-law-coproduct-is-empty
    ( is-value-Maybe x)
    ( is-exception-Maybe x)
    ( H)
    ( decide-Maybe x)

value-is-not-exception-Maybe :
  {l1 : Level} {X : UU l1} (x : Maybe X)  is-not-exception-Maybe x  X
value-is-not-exception-Maybe x H =
  value-is-value-Maybe x (is-value-is-not-exception-Maybe x H)

eq-is-not-exception-Maybe :
  {l1 : Level} {X : UU l1} (x : Maybe X) (H : is-not-exception-Maybe x) 
  inl (value-is-not-exception-Maybe x H)  x
eq-is-not-exception-Maybe x H =
  eq-is-value-Maybe x (is-value-is-not-exception-Maybe x H)
```

### The two definitions of `Maybe` are equal

```agda
equiv-Maybe-Maybe' :
  {l1 l2 : Level} {X : UU l1}  Maybe X  Maybe' X
pr1 equiv-Maybe-Maybe' (inl x) = unit-Maybe' x
pr1 equiv-Maybe-Maybe' (inr star) = exception-Maybe'
pr1 (pr1 (pr2 equiv-Maybe-Maybe')) (unit-Maybe' x) = inl x
pr1 (pr1 (pr2 equiv-Maybe-Maybe')) exception-Maybe' = inr star
pr2 (pr1 (pr2 equiv-Maybe-Maybe')) (unit-Maybe' x) = refl
pr2 (pr1 (pr2 equiv-Maybe-Maybe')) exception-Maybe' = refl
pr1 (pr2 (pr2 equiv-Maybe-Maybe')) (unit-Maybe' x) = inl x
pr1 (pr2 (pr2 equiv-Maybe-Maybe')) exception-Maybe' = inr star
pr2 (pr2 (pr2 equiv-Maybe-Maybe')) (inl x) = refl
pr2 (pr2 (pr2 equiv-Maybe-Maybe')) (inr star) = refl
```