use the original names
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Michael Zhang 2023-10-23 21:38:28 -05:00
parent 5216167465
commit bd63dba9df
1 changed files with 15 additions and 10 deletions

View File

@ -11,8 +11,10 @@ draft: true
``` ```
open import Relation.Binary.PropositionalEquality open import Relation.Binary.PropositionalEquality
open import Data.Nat open import Data.Integer
open import Data.Bool open import Data.Bool
open import Data.String
Int =
``` ```
</details> </details>
@ -96,9 +98,10 @@ With GADTs, this changes.
The key here is that different constructors of the data type can return different types of the same type family. The key here is that different constructors of the data type can return different types of the same type family.
``` ```
data Wrap : Set → Set where data Message : Set → Set₁ where
N : → Wrap S : String → Message String
B : Bool → Wrap Bool I : Int → Message Int
F : {T : Set} → (f : String → T) → Message T
``` ```
Note that in the definition, I've moved the parameter from the left side to the right. Note that in the definition, I've moved the parameter from the left side to the right.
@ -108,16 +111,18 @@ In particular, it's able to take different values for different constructors.
This allows me to write functions that are polymorphic over _all_ types, while still having the ability to refer to specific types. This allows me to write functions that are polymorphic over _all_ types, while still having the ability to refer to specific types.
```agda ```agda
unwrap : {A : Set} → Wrap A → A extract : {A : Set} → Message A → A
unwrap (N n) = n extract (S s) = s
unwrap (B b) = b extract (I i) = i
extract (F f) = f "hello"
``` ```
Note that the type signature of `unwrap` remains fully polymorphic, while each of the cases has full type information. Note that the type signature of `extract` remains fully polymorphic, while each of the cases has full type information.
This is sound because we know exactly what indexes `Wrap` could take, and the fact that there are no other ways to construct a `Wrap` means we won't ever run into a case where we would be stuck on a case we don't know how to handle. This is sound because we know exactly what indexes `Message` could take, and the fact that there are no other ways to construct a `Message` means we won't ever run into a case where we would be stuck on a case we don't know how to handle.
In a sense, each of the pattern match "arms" is giving more information about the polymorphic return type. In a sense, each of the pattern match "arms" is giving more information about the polymorphic return type.
In the `N` case, it can _only_ return `Wrap `, and in the `B` case, it can _only_ return `Wrap Bool`. In the `S` case, it can _only_ return `Message String`, and in the `I` case, it can _only_ return `Message Int`.
We can even have a polymorphic constructor case, as seen in the `F` constructor.
The same thing applies to the $\mathrm{Id}$ type, since $\mathrm{Id}$ is pretty much just a generalized and dependent data type. The same thing applies to the $\mathrm{Id}$ type, since $\mathrm{Id}$ is pretty much just a generalized and dependent data type.
The singular constructor `refl` is only defined on the index `Id A x x`, but the type has a more general `Id A x y`. The singular constructor `refl` is only defined on the index `Id A x x`, but the type has a more general `Id A x y`.