Programming in Vinyl (BayHac 2014)

Post on 23-Jun-2015

215 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Introduction to Vinyl 0.4 and its denotation in Type Theory.

Transcript

Programming in Vinyl

Jon Sterlingjonmsterling.com

May 18, 2014

Records in GHC 7.8

I Haskell records are nominally typedI They may not share field names

data R = R { x :: X }data R’ = R’ { x :: X } −− ˆ Error

Records in GHC 7.8

I Haskell records are nominally typed

I They may not share field names

data R = R { x :: X }data R’ = R’ { x :: X } −− ˆ Error

Records in GHC 7.8

I Haskell records are nominally typedI They may not share field names

data R = R { x :: X }data R’ = R’ { x :: X } −− ˆ Error

Records in GHC 7.8

I Haskell records are nominally typedI They may not share field names

data R = R { x :: X }

data R’ = R’ { x :: X } −− ˆ Error

Records in GHC 7.8

I Haskell records are nominally typedI They may not share field names

data R = R { x :: X }data R’ = R’ { x :: X } −− ˆ Error

Structural Typing

I Sharing field names and accessorsI Record types may be characterized structurally

Structural Typing

I Sharing field names and accessors

I Record types may be characterized structurally

Structural Typing

I Sharing field names and accessorsI Record types may be characterized structurally

Row Polymorphism

How do we express the type of a function which adds afield to a record?

Row Polymorphism

How do we express the type of a function which adds afield to a record?

Row Polymorphism

How do we express the type of a function which adds afield to a record?

x : {foo : A}f(x) : {foo : A, bar : B}

Row Polymorphism

How do we express the type of a function which adds afield to a record?

x : {foo : A; ~rs}f(x) : {foo : A, bar : B; ~rs}

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ where

RNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[]

(:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])

class ss ⊆ (rs :: [∗]) wherecast :: Rec rs→ Rec ss

(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss

(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t]

(⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)

lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

data (s :: Symbol) ::: (t :: ∗) = Field

data Rec :: [∗]→ ∗ whereRNil :: Rec ’[](:&) :: !t→ !(Rec rs)→ Rec ((s ::: t) ’: rs)

class s ∈ (rs :: [∗])class ss ⊆ (rs :: [∗]) where

cast :: Rec rs→ Rec ss(=:) : s ::: t→ t→ Rec ’[s ::: t](⊕) : Rec ss→ Rec ts→ Rec (ss ++ ts)lens : s ::: t ∈ rs⇒ s ::: t→ Lens’ (Rec rs) t

Roll Your Own in Haskell

f :: Rec (”foo” ::: A ’: rs)→ Rec (”bar” ::: B ’: ”foo” ::: A ’: rs)

Roll Your Own in Haskell

f :: Rec (”foo” ::: A ’: rs)→ Rec (”bar” ::: B ’: ”foo” ::: A ’: rs)

Universes a la Tarski

I A type U of codes for types.I Function ElU : U → Type.

Γ ` s : UΓ ` ElU(s) : Type

Universes a la Tarski

I A type U of codes for types.

I Function ElU : U → Type.

Γ ` s : UΓ ` ElU(s) : Type

Universes a la Tarski

I A type U of codes for types.I Function ElU : U → Type.

Γ ` s : UΓ ` ElU(s) : Type

Universes a la Tarski

I A type U of codes for types.I Function ElU : U → Type.

Γ ` s : UΓ ` ElU(s) : Type

Universes a la Tarski

Type

Universes a la Tarski

Type

Universes a la Tarski

Type

Universes a la Tarski

Type

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:

I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type

Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type

Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A

` : LabelPhone[`],Email[`] : A

s : AElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : A

s : AElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string

ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

A Closed Universe

Let A be a universe of address books:I Statics:

A : Type Label : Type Home,Office : Label

Name : A` : Label

Phone[`],Email[`] : As : A

ElA(s) : Type

I Dynamics:

ElA(Name) string ElA(Email[`]) string

ElA(Phone[`]) list(N)

Records as Products

Records as Products

Records: the product of the image of ElU in Typerestricted to a subset of U .

Records as Products

Records: the product of the image of ElU in Typerestricted to a subset of U .

recordU ∑V⊆U

∏V

ElU |V

Records as Products

Type

Records as Products

Type

×× ×

×

Records as Products

recordU ∑V⊆U

∏V

ElU |V

Example Record

recordU ∑V⊆U

∏V

ElU |V

A′ {Name,Email Work}ex : recordU

ex 〈A′, λ.{Name 7→ ”Robert Harper”;Email Work 7→ ”rwh@cs.cmu.edu”}〉

Example Record

recordU ∑V⊆U

∏V

ElU |V

A′ {Name,Email Work}

ex : recordU

ex 〈A′, λ.{Name 7→ ”Robert Harper”;Email Work 7→ ”rwh@cs.cmu.edu”}〉

Example Record

recordU ∑V⊆U

∏V

ElU |V

A′ {Name,Email Work}ex : recordU

ex 〈A′, λ.{Name 7→ ”Robert Harper”;Email Work 7→ ”rwh@cs.cmu.edu”}〉

Example Record

recordU ∑V⊆U

∏V

ElU |V

A′ {Name,Email Work}ex : recordU

ex 〈A′, λ.{Name 7→ ”Robert Harper”;Email Work 7→ ”rwh@cs.cmu.edu”}〉

Presheaves

A presheaf on some space X is a functorO(X)op → Type, where O is the category of open sets ofX for whatever topology you have chosen.

Presheaves

A presheaf on some space X is a functorO(X)op → Type, where O is the category of open sets ofX for whatever topology you have chosen.

Topologies on some space X

I What are the open sets on X?I The empty set and X are open setsI The union of open sets is openI Finite intersections of open sets are open

Topologies on some space X

I What are the open sets on X?

I The empty set and X are open setsI The union of open sets is openI Finite intersections of open sets are open

Topologies on some space X

I What are the open sets on X?I The empty set and X are open setsI The union of open sets is openI Finite intersections of open sets are open

Records are Presheaves

I Let O = P, the discrete topologyI Then records on a universe X give rise to a presheafR: subset inclusions are taken to casts from larger tosmaller records

for V ⊆ X R(V ) :≡∏V

ElX |V : Type

for i : V ↪→ U R(i) :≡ cast : R(U)→ R(V )

Records are Presheaves

I Let O = P, the discrete topology

I Then records on a universe X give rise to a presheafR: subset inclusions are taken to casts from larger tosmaller records

for V ⊆ X R(V ) :≡∏V

ElX |V : Type

for i : V ↪→ U R(i) :≡ cast : R(U)→ R(V )

Records are Presheaves

I Let O = P, the discrete topologyI Then records on a universe X give rise to a presheafR: subset inclusions are taken to casts from larger tosmaller records

for V ⊆ X R(V ) :≡∏V

ElX |V : Type

for i : V ↪→ U R(i) :≡ cast : R(U)→ R(V )

Records are Presheaves

I Let O = P, the discrete topologyI Then records on a universe X give rise to a presheafR: subset inclusions are taken to casts from larger tosmaller records

for V ⊆ X R(V ) :≡∏V

ElX |V : Type

for i : V ↪→ U R(i) :≡ cast : R(U)→ R(V )

Records are Presheaves

I Let O = P, the discrete topologyI Then records on a universe X give rise to a presheafR: subset inclusions are taken to casts from larger tosmaller records

for V ⊆ X R(V ) :≡∏V

ElX |V : Type

for i : V ↪→ U R(i) :≡ cast : R(U)→ R(V )

Records are Sheaves

For a cover U =⋃

i Ui on X, then:

e = λr.λi. castUi(r)

p = λf.λi.λj. castUi∩Uj(f(i))

q = λf.λi.λj. castUi∩Uj(f(j))

Records are Sheaves

For a cover U =⋃

i Ui on X, then:

R(U)∏

iR(Ui)∏

i,jR(Ui ∩ Uj)e p

q

is an equalizer, where

e = λr.λi. castUi(r)

p = λf.λi.λj. castUi∩Uj(f(i))

q = λf.λi.λj. castUi∩Uj(f(j))

Records are SheavesFor a cover U =

⋃i Ui on X, then:

R(U)∏

iR(Ui)∏

i,jR(Ui ∩ Uj)

Γ

e

m!u

p

q

where

e = λr.λi. castUi(r)

p = λf.λi.λj. castUi∩Uj(f(i))

q = λf.λi.λj. castUi∩Uj(f(j))

Corecords as Sums

Corecords as Sums

Corecords (extensible variants): the sum of the image ofElU in Type restricted to a subset of U .

Corecords as Sums

Corecords (extensible variants): the sum of the image ofElU in Type restricted to a subset of U .

corecordU ∑V⊆U

∑V

ElU |V

Corecords as Sums

Type

Corecords as Sums

Type

++ +

+

Corecords as Sums

corecordU ∑V⊆U

∑V

ElU |V

Doing it in Haskell

I Create a universe U at the type-levelI Use type families to approximate ElUI Parameterize Rec by U , ElU?

Doing it in Haskell

I Create a universe U at the type-level

I Use type families to approximate ElUI Parameterize Rec by U , ElU?

Doing it in Haskell

I Create a universe U at the type-levelI Use type families to approximate ElU

I Parameterize Rec by U , ElU?

Doing it in Haskell

I Create a universe U at the type-levelI Use type families to approximate ElUI Parameterize Rec by U , ElU?

Records in Haskell

data Rec :: (U → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell

data Rec :: (U → ∗)→ [ U ]→ ∗ where

RNil :: Rec elU ’[](:&) :: !(elU r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell

data Rec :: (U → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[]

(:&) :: !(elU r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell

data Rec :: (U → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell (Actually)

data TyFun :: ∗ → ∗ → ∗type family (f :: TyFun k l→ ∗) $ (x :: k) :: l

data Rec :: (TyFun U ∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU $ r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell (Actually)

data TyFun :: ∗ → ∗ → ∗

type family (f :: TyFun k l→ ∗) $ (x :: k) :: l

data Rec :: (TyFun U ∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU $ r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell (Actually)

data TyFun :: ∗ → ∗ → ∗type family (f :: TyFun k l→ ∗) $ (x :: k) :: l

data Rec :: (TyFun U ∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU $ r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Records in Haskell (Actually)

data TyFun :: ∗ → ∗ → ∗type family (f :: TyFun k l→ ∗) $ (x :: k) :: l

data Rec :: (TyFun U ∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU $ r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Recovering HList

data Id :: (TyFun k k)→ ∗ wheretype instance Id $ x = x

type HList rs = Rec Id rs

ex :: HList [Z, Bool, String]ex = 34 :& True :& ”vinyl” :& RNil

Recovering HList

data Id :: (TyFun k k)→ ∗ wheretype instance Id $ x = x

type HList rs = Rec Id rs

ex :: HList [Z, Bool, String]ex = 34 :& True :& ”vinyl” :& RNil

Recovering HList

data Id :: (TyFun k k)→ ∗ wheretype instance Id $ x = x

type HList rs = Rec Id rs

ex :: HList [Z, Bool, String]ex = 34 :& True :& ”vinyl” :& RNil

Recovering HList

data Id :: (TyFun k k)→ ∗ wheretype instance Id $ x = x

type HList rs = Rec Id rs

ex :: HList [Z, Bool, String]

ex = 34 :& True :& ”vinyl” :& RNil

Recovering HList

data Id :: (TyFun k k)→ ∗ wheretype instance Id $ x = x

type HList rs = Rec Id rs

ex :: HList [Z, Bool, String]ex = 34 :& True :& ”vinyl” :& RNil

Validating Records

bob :: Rec ElA [Name, Email Work]

bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

validateName :: String→ Either Error StringvalidateEmail :: String→ Either Error StringvalidatePhone :: [N]→ Either Error [N]

*unnnnnhhh...*

validateContact:: Rec ElA [Name, Email Work]→ Either Error (Rec ElA [Name, Email Work])

Validating Records

bob :: Rec ElA [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

validateName :: String→ Either Error StringvalidateEmail :: String→ Either Error StringvalidatePhone :: [N]→ Either Error [N]

*unnnnnhhh...*

validateContact:: Rec ElA [Name, Email Work]→ Either Error (Rec ElA [Name, Email Work])

Validating Records

bob :: Rec ElA [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

validateName :: String→ Either Error StringvalidateEmail :: String→ Either Error StringvalidatePhone :: [N]→ Either Error [N]

*unnnnnhhh...*

validateContact:: Rec ElA [Name, Email Work]→ Either Error (Rec ElA [Name, Email Work])

Validating Records

bob :: Rec ElA [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

validateName :: String→ Either Error StringvalidateEmail :: String→ Either Error StringvalidatePhone :: [N]→ Either Error [N]

*unnnnnhhh...*

validateContact:: Rec ElA [Name, Email Work]→ Either Error (Rec ElA [Name, Email Work])

Validating Records

bob :: Rec ElA [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

validateName :: String→ Either Error StringvalidateEmail :: String→ Either Error StringvalidatePhone :: [N]→ Either Error [N]

*unnnnnhhh...*

validateContact:: Rec ElA [Name, Email Work]→ Either Error (Rec ElA [Name, Email Work])

Welp.

Effects inside records

data Rec :: (TyFun U ∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU ’[](:&) :: !(elU $ r)→ !(Rec elU rs)→ Rec elU (r ’: rs)

Effects inside records

data Rec :: (TyFun U ∗ → ∗)→ (∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU f ’[](:&) :: !(f (elU $ r))→ !(Rec elU f rs)→ Rec elU f (r ’: rs)

(=:) : Applicative f⇒ sing r→ elU $ r→ Rec elU f ’[r]k =: x = pure x :& RNil

(⇐\): sing r→ f (elU $ r)→ Rec elU f ’[r]k⇐\ x = x :& RNil

Effects inside records

data Rec :: (TyFun U ∗ → ∗)→ (∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU f ’[](:&) :: !(f (elU $ r))→ !(Rec elU f rs)→ Rec elU f (r ’: rs)

(=:) : Applicative f⇒ sing r→ elU $ r→ Rec elU f ’[r]

k =: x = pure x :& RNil

(⇐\): sing r→ f (elU $ r)→ Rec elU f ’[r]k⇐\ x = x :& RNil

Effects inside records

data Rec :: (TyFun U ∗ → ∗)→ (∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU f ’[](:&) :: !(f (elU $ r))→ !(Rec elU f rs)→ Rec elU f (r ’: rs)

(=:) : Applicative f⇒ sing r→ elU $ r→ Rec elU f ’[r]k =: x = pure x :& RNil

(⇐\): sing r→ f (elU $ r)→ Rec elU f ’[r]k⇐\ x = x :& RNil

Effects inside records

data Rec :: (TyFun U ∗ → ∗)→ (∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU f ’[](:&) :: !(f (elU $ r))→ !(Rec elU f rs)→ Rec elU f (r ’: rs)

(=:) : Applicative f⇒ sing r→ elU $ r→ Rec elU f ’[r]k =: x = pure x :& RNil

(⇐\): sing r→ f (elU $ r)→ Rec elU f ’[r]

k⇐\ x = x :& RNil

Effects inside records

data Rec :: (TyFun U ∗ → ∗)→ (∗ → ∗)→ [ U ]→ ∗ whereRNil :: Rec elU f ’[](:&) :: !(f (elU $ r))→ !(Rec elU f rs)→ Rec elU f (r ’: rs)

(=:) : Applicative f⇒ sing r→ elU $ r→ Rec elU f ’[r]k =: x = pure x :& RNil

(⇐\): sing r→ f (elU $ r)→ Rec elU f ’[r]k⇐\ x = x :& RNil

Compositional Validation

type RecA = Rec ElA

bob :: RecA Identity [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

Compositional Validation

type RecA = Rec ElAbob :: RecA Identity [Name, Email Work]

bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

Compositional Validation

type RecA = Rec ElAbob :: RecA Identity [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

Compositional Validation

type RecA = Rec ElAbob :: RecA Identity [Name, Email Work]bob = Name =: ”Robert Harper”⊕ Email Work =: ”rwh@cs.cmu.edu”

Compositional Validation

type Validator a = a→ Either Error a

validateName :: RecA Validator ’[Name]validatePhone :: ∀`. RecA Validator ’[Phone `]validateEmail :: ∀`. RecA Validator ’[Email `]

type TotalContact =[ Name, Email Home, Email Work, Phone Home, Phone Work ]

validateContact :: RecA Validator TotalContactvalidateContact = validateName

⊕ validateEmail⊕ validateEmail⊕ validatePhone⊕ validatePhone

Compositional Validation

type Validator a = a→ Either Error avalidateName :: RecA Validator ’[Name]validatePhone :: ∀`. RecA Validator ’[Phone `]validateEmail :: ∀`. RecA Validator ’[Email `]

type TotalContact =[ Name, Email Home, Email Work, Phone Home, Phone Work ]

validateContact :: RecA Validator TotalContactvalidateContact = validateName

⊕ validateEmail⊕ validateEmail⊕ validatePhone⊕ validatePhone

Compositional Validation

type Validator a = a→ Either Error avalidateName :: RecA Validator ’[Name]validatePhone :: ∀`. RecA Validator ’[Phone `]validateEmail :: ∀`. RecA Validator ’[Email `]

type TotalContact =[ Name, Email Home, Email Work, Phone Home, Phone Work ]

validateContact :: RecA Validator TotalContactvalidateContact = validateName

⊕ validateEmail⊕ validateEmail⊕ validatePhone⊕ validatePhone

Compositional Validation

type Validator a = a→ Either Error avalidateName :: RecA Validator ’[Name]validatePhone :: ∀`. RecA Validator ’[Phone `]validateEmail :: ∀`. RecA Validator ’[Email `]

type TotalContact =[ Name, Email Home, Email Work, Phone Home, Phone Work ]

validateContact :: RecA Validator TotalContactvalidateContact = validateName

⊕ validateEmail⊕ validateEmail⊕ validatePhone⊕ validatePhone

Record Operators

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }

type Validator = Lift (→) Identity (Either Error)

( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rs

rdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

Record Operators

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }

type Validator = Lift (→) Identity (Either Error)

( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rs

rdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

Record Operators

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }

type Validator = Lift (→) Identity (Either Error)

( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rs

rdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

Record Operators

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }

type Validator = Lift (→) Identity (Either Error)

( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rs

rdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

Record Operators

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }

type Validator = Lift (→) Identity (Either Error)

( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rs

rdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

Compositional Validation

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }type Validator = Lift (→) Identity (Either Error)( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rsrdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

validateContact :: RecA Validator TotalContact

bobValid :: RecA (Either Error) [Name, Email Work]bobValid = cast validateContact ? bob

validBob :: Either Error (RecA Identity [Name, Email Work])validBob = rdist bobValid

Compositional Validation

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }type Validator = Lift (→) Identity (Either Error)( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rsrdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

validateContact :: RecA Validator TotalContact

bobValid :: RecA (Either Error) [Name, Email Work]bobValid = cast validateContact ? bob

validBob :: Either Error (RecA Identity [Name, Email Work])validBob = rdist bobValid

Compositional Validation

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }type Validator = Lift (→) Identity (Either Error)( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rsrdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

validateContact :: RecA Validator TotalContact

bobValid :: RecA (Either Error) [Name, Email Work]

bobValid = cast validateContact ? bob

validBob :: Either Error (RecA Identity [Name, Email Work])validBob = rdist bobValid

Compositional Validation

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }type Validator = Lift (→) Identity (Either Error)( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rsrdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

validateContact :: RecA Validator TotalContact

bobValid :: RecA (Either Error) [Name, Email Work]bobValid = cast validateContact ? bob

validBob :: Either Error (RecA Identity [Name, Email Work])validBob = rdist bobValid

Compositional Validation

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }type Validator = Lift (→) Identity (Either Error)( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rsrdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

validateContact :: RecA Validator TotalContact

bobValid :: RecA (Either Error) [Name, Email Work]bobValid = cast validateContact ? bob

validBob :: Either Error (RecA Identity [Name, Email Work])

validBob = rdist bobValid

Compositional Validation

newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }type Validator = Lift (→) Identity (Either Error)( ? ) :: RecU (Lift (→) f g) rs→ RecU f rs→ RecU g rsrdist :: Applicative f⇒ RecU f rs→ f (RecU Identity rs)

validateContact :: RecA Validator TotalContact

bobValid :: RecA (Either Error) [Name, Email Work]bobValid = cast validateContact ? bob

validBob :: Either Error (RecA Identity [Name, Email Work])validBob = rdist bobValid

Laziness as an effect

newtype Identity a = Identity { runIdentity :: a }data Thunk a = Thunk { unThunk :: a }

type PlainRecU rs = RecU Identity rstype LazyRecU rs = RecU Thunk rs

Laziness as an effect

newtype Identity a = Identity { runIdentity :: a }

data Thunk a = Thunk { unThunk :: a }

type PlainRecU rs = RecU Identity rstype LazyRecU rs = RecU Thunk rs

Laziness as an effect

newtype Identity a = Identity { runIdentity :: a }data Thunk a = Thunk { unThunk :: a }

type PlainRecU rs = RecU Identity rstype LazyRecU rs = RecU Thunk rs

Laziness as an effect

newtype Identity a = Identity { runIdentity :: a }data Thunk a = Thunk { unThunk :: a }

type PlainRecU rs = RecU Identity rs

type LazyRecU rs = RecU Thunk rs

Laziness as an effect

newtype Identity a = Identity { runIdentity :: a }data Thunk a = Thunk { unThunk :: a }

type PlainRecU rs = RecU Identity rstype LazyRecU rs = RecU Thunk rs

Concurrent Records with Async

fetchName :: RecA IO ’[Name]fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

fetchName :: RecA IO ’[Name]

fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

fetchName :: RecA IO ’[Name]fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

fetchName :: RecA IO ’[Name]fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]

fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

fetchName :: RecA IO ’[Name]fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

fetchName :: RecA IO ’[Name]fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]

fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

fetchName :: RecA IO ’[Name]fetchName = Name⇐\ someOperation

fetchWorkEmail :: RecA IO ’[Email Work]fetchWorkEmail = Email Work⇐\ anotherOperation

fetchBob :: RecA IO [Name, Email Work]fetchBob = fetchName ⊕ fetchWorkEmail

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])concurrentBob = rdist bobConcurrently

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])concurrentBob = rdist bobConcurrently

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])concurrentBob = rdist bobConcurrently

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]

bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])concurrentBob = rdist bobConcurrently

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])concurrentBob = rdist bobConcurrently

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])

concurrentBob = rdist bobConcurrently

Concurrent Records with Async

newtype Concurrently a= Concurrently { runConcurrently :: IO a }

( $ ) :: (∀ a. f a→ g a)→ RecU f rs→ RecU g rs

bobConcurrently :: RecA Concurrently [Name, Email Work]bobConcurrently = Concurrently $ fetchBob

concurrentBob :: Concurrently (RecA Identity [...])concurrentBob = rdist bobConcurrently

Concurrent Records with Async

fetchBob :: RecA IO [Name, Email Work]bobConcurrently :: RecA Concurrently [Name, Email Work]concurrentBob :: Concurrently (RecA Identity [...])

bob :: IO (RecA Identity [Name, Email Work])bob = runConcurrently concurrentBob

Concurrent Records with Async

fetchBob :: RecA IO [Name, Email Work]bobConcurrently :: RecA Concurrently [Name, Email Work]concurrentBob :: Concurrently (RecA Identity [...])

bob :: IO (RecA Identity [Name, Email Work])bob = runConcurrently concurrentBob

Concurrent Records with Async

fetchBob :: RecA IO [Name, Email Work]bobConcurrently :: RecA Concurrently [Name, Email Work]concurrentBob :: Concurrently (RecA Identity [...])

bob :: IO (RecA Identity [Name, Email Work])

bob = runConcurrently concurrentBob

Concurrent Records with Async

fetchBob :: RecA IO [Name, Email Work]bobConcurrently :: RecA Concurrently [Name, Email Work]concurrentBob :: Concurrently (RecA Identity [...])

bob :: IO (RecA Identity [Name, Email Work])bob = runConcurrently concurrentBob

Containers: The Syntax for Data Types

container : Type

U : Type ElU : U → TypeU / ElU : container

C : containerC.Sh : Type

C U / ElUC.Sh U

C : containerC.Po : C.Sh→ Type

C U / ElUC.Po ElU

Containers: The Syntax for Data Types

container : TypeU : Type ElU : U → TypeU / ElU : container

C : containerC.Sh : Type

C U / ElUC.Sh U

C : containerC.Po : C.Sh→ Type

C U / ElUC.Po ElU

Containers: The Syntax for Data Types

container : TypeU : Type ElU : U → TypeU / ElU : container

C : containerC.Sh : Type

C U / ElUC.Sh U

C : containerC.Po : C.Sh→ Type

C U / ElUC.Po ElU

Containers: The Syntax for Data Types

container : TypeU : Type ElU : U → TypeU / ElU : container

C : containerC.Sh : Type

C U / ElUC.Sh U

C : containerC.Po : C.Sh→ Type

C U / ElUC.Po ElU

Containers: The Syntax for Data Types

container : TypeU : Type ElU : U → TypeU / ElU : container

C : containerC.Sh : Type

C U / ElUC.Sh U

C : containerC.Po : C.Sh→ Type

C U / ElUC.Po ElU

Containers: The Syntax for Data Types

container : TypeU : Type ElU : U → TypeU / ElU : container

C : containerC.Sh : Type

C U / ElUC.Sh U

C : containerC.Po : C.Sh→ Type

C U / ElUC.Po ElU

Restricting Containers

C : container V ⊆ C.ShC|V : container

C U / ElUC|V V / ElU |V

Restricting Containers

C : container V ⊆ C.ShC|V : container

C U / ElUC|V V / ElU |V

Container Lifting

C : container F : Type→ TypeC ↑ F : container

C U / ElUC ↑ F U / F ◦ ElU

Container Lifting

C : container F : Type→ TypeC ↑ F : container

C U / ElUC ↑ F U / F ◦ ElU

A Menagerie of Quantifiers

A Menagerie of Quantifiers

Dependent Products:

Γ ` A : Type Γ, x : A ` B : TypeΓ `

∏AB : Type

Γ, x : A ` e : B[x]

Γ ` λx.e :∏

AB

A Menagerie of Quantifiers

Dependent Sums:

Γ ` A : Type Γ, x : A ` B : TypeΓ `

∑AB : Type

Γ ` a : A Γ ` b : B[a]

Γ ` 〈a, b〉 :∑

AB

A Menagerie of Quantifiers

Inductive Types:

Γ ` A : Type Γ, x : A ` B : TypeΓ `WAB : Type

Γ ` a : A Γ, v : B[a] ` b : WAB

Γ ` sup(a; v. b) : WAB

A Menagerie of Quantifiers

Coinductive Types:

Γ ` A : Type Γ, x : A ` B : TypeΓ ` MAB : Type

Γ ` a : A Γ, v : B[a] ` b :∞ (MAB)

Γ ` inf(a; v. b) : MAB

A Scheme for Quantifiers

Γ, A : Type, (x : A ` B : Type) ` QAB : TypeΓ ` Q quantifier

A Scheme for Quantifiers

Γ, A : Type, (x : A ` B : Type) ` QAB : TypeΓ ` Q quantifier

Quantifiers Give Containers Semantics

Γ, A : Type, (x : A ` B : Type) ` QAB : TypeΓ ` Q quantifier

C : container Q quantifier

JCKQ : Type

C U / ElUJCKQ QUElU

Quantifiers Give Containers Semantics

Γ, A : Type, (x : A ` B : Type) ` QAB : TypeΓ ` Q quantifier

C : container Q quantifier

JCKQ : Type

C U / ElUJCKQ QUElU

Quantifiers Give Containers Semantics

Γ, A : Type, (x : A ` B : Type) ` QAB : TypeΓ ` Q quantifier

C : container Q quantifier

JCKQ : Type

C U / ElUJCKQ QUElU

Vinyl Records as Containers

Records and corecords are finite products and sumsrespectively.

Rec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΠ

CoRec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΣ

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KW

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KM

Vinyl Records as Containers

Records and corecords are finite products and sumsrespectively.

Rec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΠ

CoRec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΣ

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KW

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KM

Vinyl Records as Containers

Records and corecords are finite products and sumsrespectively.

Rec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΠ

CoRec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΣ

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KW

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KM

Vinyl Records as Containers

Records and corecords are finite products and sumsrespectively.

Rec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΠ

CoRec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΣ

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KW

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KM

Vinyl Records as Containers

Records and corecords are finite products and sumsrespectively.

Rec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΠ

CoRec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΣ

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KW

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KM

Vinyl Records as Containers

Records and corecords are finite products and sumsrespectively.

Rec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΠ

CoRec ElU F rs ∼= J(U / ElU)|rs3− ↑ F KΣ

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KW

??? ElU F rs ∼= J(U / ElU)|rs3− ↑ F KM

Questions

top related