# The universal property of dependent function types

```agda
module foundation.universal-property-dependent-function-types where
```

<details><summary>Imports</summary>

```agda
open import foundation.dependent-pair-types
open import foundation.function-extensionality
open import foundation.identity-types
open import foundation.spans-families-of-types
open import foundation.terminal-spans-families-of-types
open import foundation.universe-levels

open import foundation-core.contractible-maps
open import foundation-core.contractible-types
open import foundation-core.equivalences
open import foundation-core.functoriality-dependent-function-types
open import foundation-core.functoriality-dependent-pair-types
```

</details>

## Idea

Consider a family of types `B` over `A`. Then the dependent function type
`(a : A) ā†’ B a` naturally has the structure of a
[span](foundation.spans-families-of-types.md) on the family of types `B` over
`A`, where for each `a : A` the map

```text
  ((x : A) ā†’ B x) ā†’ B a
```

is given by evaluation at `a`.

A span `š’® := (S , f)` is said to satisfy the
{{#concept "universal property of dependent function types" Agda=universal-property-dependent-function-types}}
if for any type `T` the map

```text
  (T ā†’ S) ā†’ ((x : A) ā†’ T ā†’ B x)
```

given by `h ā†¦ Ī» x t ā†’ f x (h t)` is an
[equivalence](foundation-core.equivalences.md). The dependent function type
`(x : A) ā†’ B x` equipped with the span structure defined above satisfies the
universal property of dependent function types.

In
[`foundation.dependent-function-types`](foundation.dependent-function-types.md)
we show that dependent function types satisfy the universal property of
dependent function types. In this file we also show that the universal property
of dependent function types is equivalent to being a
[terminal span](foundation.terminal-spans-families-of-types.md) on the type
family `B`.

## Definitions

### The universal property of dependent function types

```agda
module _
  {l1 l2 l3 : Level} {A : UU l1} {B : A ā†’ UU l2} (š’® : span-type-family l3 B)
  where

  ev-span-type-family :
    {l : Level} (T : UU l) ā†’
    (T ā†’ spanning-type-span-type-family š’®) ā†’ (x : A) ā†’ T ā†’ B x
  ev-span-type-family T h x t = map-span-type-family š’® x (h t)

  universal-property-dependent-function-types : UUĻ‰
  universal-property-dependent-function-types =
    {l : Level} (T : UU l) ā†’ is-equiv (ev-span-type-family T)
```

## Properties

### A span on a family of types satisfies the universal property of dependent function types if and only if it is terminal

```agda
module _
  {l1 l2 l3 : Level} {A : UU l1} {B : A ā†’ UU l2} (š’® : span-type-family l3 B)
  where

  abstract
    is-terminal-universal-property-dependent-function-types :
      universal-property-dependent-function-types š’® ā†’
      is-terminal-span-type-family š’®
    is-terminal-universal-property-dependent-function-types U š’Æ =
      is-contr-equiv' _
        ( equiv-tot
          ( Ī» h ā†’
            ( equiv-Ī -equiv-family
              ( Ī» a ā†’
                ( equiv-Ī -equiv-family (Ī» t ā†’ equiv-inv _ _)) āˆ˜e
                ( equiv-funext))) āˆ˜e
            ( equiv-funext)))
        ( is-contr-map-is-equiv
          ( U (spanning-type-span-type-family š’Æ))
          ( map-span-type-family š’Æ))

  abstract
    universal-property-dependent-function-types-is-terminal :
      is-terminal-span-type-family š’® ā†’
      universal-property-dependent-function-types š’®
    universal-property-dependent-function-types-is-terminal U T =
      is-equiv-is-contr-map
        ( Ī» g ā†’
          is-contr-equiv _
            ( equiv-tot
              ( Ī» h ā†’
                ( equiv-Ī -equiv-family
                  ( Ī» a ā†’
                    ( equiv-Ī -equiv-family (Ī» t ā†’ equiv-inv _ _)) āˆ˜e
                    ( equiv-funext))) āˆ˜e
                ( equiv-funext)))
            ( U (T , g)))
```

## See also

- [Dependent function types](foundation.dependent-function-types.md)