Programming in Vinyl
Jon Sterling
jonmsterling.com
May 18, 2014
Records in GHC 7.8
Records in GHC 7.8
Haskell records are nominally typed
Records in GHC 7.8
Haskell records are nominally typed
They may not share field names
Records in GHC 7.8
Haskell records are nominally typed
They may not share field names
data R = R { x :: X }
Records in GHC 7.8
Haskell records are nominally typed
They may not share field names
data R = R { x :: X }
data R’ = R’ { x :: X } −− ˆ Error
Structural Typing
Structural Typing
Sharing field names and accessors
Structural Typing
Sharing field names and accessors
Record types may be characterized structurally
Row Polymorphism
Row Polymorphism
How do we express the type of a function which adds a
field to a record?
Row Polymorphism
How do we express the type of a function which adds a
field 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 a
field to a record?
x : {foo : A; rs}
f(x) : {foo : A, bar : B; rs}
Roll Your Own in Haskell
Roll Your Own in Haskell
data (s :: Symbol) ::: (t :: ∗) = Field
Roll Your Own in Haskell
data (s :: Symbol) ::: (t :: ∗) = Field
data Rec :: [∗] → ∗ where
Roll Your Own in Haskell
data (s :: Symbol) ::: (t :: ∗) = Field
data Rec :: [∗] → ∗ where
RNil :: Rec ’[]
Roll Your Own in Haskell
data (s :: Symbol) ::: (t :: ∗) = Field
data Rec :: [∗] → ∗ where
RNil :: Rec ’[]
(:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
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 :: [∗])
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
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]
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)
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
Roll Your Own in Haskell
f :: Rec (”foo” ::: A ’: rs)
→ Rec (”bar” ::: B ’: ”foo” ::: A ’: rs)
Universes `a la Tarski
Universes `a la Tarski
A type U of codes for types.
Universes `a la Tarski
A type U of codes for types.
Function ElU : U → Type.
Universes `a la Tarski
A type U of codes for types.
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
A Closed Universe
Let A be a universe of address books:
A Closed Universe
Let A be a universe of address books:
Statics:
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
: Label
Phone[ ], Email[ ] : A
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
: Label
Phone[ ], Email[ ] : A
s : A
ElA(s) : Type
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
: Label
Phone[ ], Email[ ] : A
s : A
ElA(s) : Type
Dynamics:
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
: Label
Phone[ ], Email[ ] : A
s : A
ElA(s) : Type
Dynamics:
ElA(Name) string
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
: Label
Phone[ ], Email[ ] : A
s : A
ElA(s) : Type
Dynamics:
ElA(Name) string ElA(Email[ ]) string
A Closed Universe
Let A be a universe of address books:
Statics:
A : Type Label : Type Home, Office : Label
Name : A
: Label
Phone[ ], Email[ ] : A
s : A
ElA(s) : Type
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 Type
restricted to a subset of U.
Records as Products
Records: the product of the image of ElU in Type
restricted 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
Example Record
recordU
V⊆U V
ElU |V
A {Name, Email Work}
Example Record
recordU
V⊆U V
ElU |V
A {Name, Email Work}
ex : recordU
Example Record
recordU
V⊆U V
ElU |V
A {Name, Email Work}
ex : recordU
ex A , λ.
{Name → ”Robert Harper”;
Email Work → ”rwh@cs.cmu.edu”}
Presheaves
Presheaves
A presheaf on some space X is a functor
O(X)op
→ Type, where O is the category of open sets of
X for whatever topology you have chosen.
Topologies on some space X
Topologies on some space X
What are the open sets on X?
Topologies on some space X
What are the open sets on X?
The empty set and X are open sets
The union of open sets is open
Finite intersections of open sets are open
Records are Presheaves
Records are Presheaves
Let O = P, the discrete topology
Records are Presheaves
Let O = P, the discrete topology
Then records on a universe X give rise to a presheaf
R: subset inclusions are taken to casts from larger to
smaller records
Records are Presheaves
Let O = P, the discrete topology
Then records on a universe X give rise to a presheaf
R: subset inclusions are taken to casts from larger to
smaller records
for V ⊆ X R(V ) :≡
V
ElX|V : Type
Records are Presheaves
Let O = P, the discrete topology
Then records on a universe X give rise to a presheaf
R: subset inclusions are taken to casts from larger to
smaller records
for V ⊆ X R(V ) :≡
V
ElX|V : Type
for i : V → U R(i) :≡ cast : R(U) → R(V )
Records are Sheaves
Records are Sheaves
For a cover U = i Ui on X, then:
R(U) i R(Ui) i,j R(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 Sheaves
For a cover U = i Ui on X, then:
R(U) i R(Ui) i,j R(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 of
ElU in Type restricted to a subset of U.
Corecords as Sums
Corecords (extensible variants): the sum of the image of
ElU 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
Doing it in Haskell
Create a universe U at the type-level
Doing it in Haskell
Create a universe U at the type-level
Use type families to approximate ElU
Doing it in Haskell
Create a universe U at the type-level
Use type families to approximate ElU
Parameterize Rec by U, ElU ?
Records in Haskell
Records in Haskell
data Rec :: (U → ∗) → [ U ] → ∗ where
Records in Haskell
data Rec :: (U → ∗) → [ U ] → ∗ where
RNil :: Rec elU ’[]
Records in Haskell
data Rec :: (U → ∗) → [ U ] → ∗ where
RNil :: Rec elU ’[]
(:&) :: !(elU r) → !(Rec elU rs) → Rec elU (r ’: rs)
Records in Haskell (Actually)
Records in Haskell (Actually)
data TyFun :: ∗ → ∗ → ∗
Records in Haskell (Actually)
data TyFun :: ∗ → ∗ → ∗
type family (f :: TyFun k l → ∗) $ (x :: k) :: l
Records in Haskell (Actually)
data TyFun :: ∗ → ∗ → ∗
type family (f :: TyFun k l → ∗) $ (x :: k) :: l
data Rec :: (TyFun U ∗ → ∗) → [ U ] → ∗ where
RNil :: Rec elU ’[]
(:&) :: !(elU $ r) → !(Rec elU rs) → Rec elU (r ’: rs)
Recovering HList
Recovering HList
data Id :: (TyFun k k) → ∗ where
type instance Id $ x = x
Recovering HList
data Id :: (TyFun k k) → ∗ where
type instance Id $ x = x
type HList rs = Rec Id rs
Recovering HList
data Id :: (TyFun k k) → ∗ where
type instance Id $ x = x
type HList rs = Rec Id rs
ex :: HList [Z, Bool, String]
Recovering HList
data Id :: (TyFun k k) → ∗ where
type 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]
Validating Records
bob :: Rec ElA [Name, Email Work]
bob = Name =: ”Robert Harper”
⊕ Email Work =: ”rwh@cs.cmu.edu”
Validating Records
bob :: Rec ElA [Name, Email Work]
bob = Name =: ”Robert Harper”
⊕ Email Work =: ”rwh@cs.cmu.edu”
validateName :: String → Either Error String
validateEmail :: String → Either Error String
validatePhone :: [N] → Either Error [N]
Validating Records
bob :: Rec ElA [Name, Email Work]
bob = Name =: ”Robert Harper”
⊕ Email Work =: ”rwh@cs.cmu.edu”
validateName :: String → Either Error String
validateEmail :: String → Either Error String
validatePhone :: [N] → Either Error [N]
*unnnnnhhh...*
Validating Records
bob :: Rec ElA [Name, Email Work]
bob = Name =: ”Robert Harper”
⊕ Email Work =: ”rwh@cs.cmu.edu”
validateName :: String → Either Error String
validateEmail :: String → Either Error String
validatePhone :: [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 ] → ∗ where
RNil :: Rec elU ’[]
(:&) :: !(elU $ r) → !(Rec elU rs) → Rec elU (r ’: rs)
Effects inside records
data Rec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where
RNil :: Rec elU f ’[]
(:&) :: !(f (elU $ r)) → !(Rec elU f rs) → Rec elU f (r ’: rs)
Effects inside records
data Rec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where
RNil :: 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]
Effects inside records
data Rec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where
RNil :: 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
Effects inside records
data Rec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where
RNil :: 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]
Effects inside records
data Rec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where
RNil :: 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
Compositional Validation
type RecA = Rec ElA
bob :: RecA Identity [Name, Email Work]
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 ElA
bob :: RecA Identity [Name, Email Work]
bob = Name =: ”Robert Harper”
⊕ Email Work =: ”rwh@cs.cmu.edu”
Compositional Validation
type Validator a = a → Either Error a
Compositional Validation
type Validator a = a → Either Error a
validateName :: RecA Validator ’[Name]
validatePhone :: ∀ . RecA Validator ’[Phone ]
validateEmail :: ∀ . RecA Validator ’[Email ]
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 ]
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 TotalContact
validateContact = validateName
⊕ validateEmail
⊕ validateEmail
⊕ validatePhone
⊕ validatePhone
Record Operators
Record Operators
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
Record Operators
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
type Validator = Lift (→) Identity (Either Error)
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
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 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 rs
rdist :: Applicative f ⇒ RecU f rs → f (RecU Identity rs)
validateContact :: RecA Validator TotalContact
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 rs
rdist :: Applicative f ⇒ RecU f rs → f (RecU Identity rs)
validateContact :: RecA Validator TotalContact
bobValid :: RecA (Either Error) [Name, Email Work]
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 rs
rdist :: Applicative f ⇒ RecU f rs → f (RecU Identity rs)
validateContact :: RecA Validator TotalContact
bobValid :: RecA (Either Error) [Name, Email Work]
bobValid = cast validateContact bob
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 rs
rdist :: 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])
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 rs
rdist :: 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
Laziness as an effect
newtype Identity a = Identity { runIdentity :: a }
Laziness as an effect
newtype Identity a = Identity { runIdentity :: a }
data Thunk a = Thunk { unThunk :: a }
Laziness as an effect
newtype Identity a = Identity { runIdentity :: a }
data Thunk a = Thunk { unThunk :: a }
type PlainRecU rs = RecU Identity 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
Concurrent Records with Async
Concurrent Records with Async
fetchName :: RecA IO ’[Name]
Concurrent Records with Async
fetchName :: RecA IO ’[Name]
fetchName = Name ⇐ someOperation
Concurrent Records with Async
fetchName :: RecA IO ’[Name]
fetchName = Name ⇐ someOperation
fetchWorkEmail :: RecA IO ’[Email Work]
Concurrent Records with Async
fetchName :: RecA IO ’[Name]
fetchName = Name ⇐ someOperation
fetchWorkEmail :: RecA IO ’[Email Work]
fetchWorkEmail = Email Work ⇐ anotherOperation
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]
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
Concurrent Records with Async
newtype Concurrently a
= Concurrently { runConcurrently :: IO a }
Concurrent Records with Async
newtype Concurrently a
= Concurrently { runConcurrently :: IO a }
( $ ) :: (∀ a. f a → g a) → RecU f rs → RecU g rs
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]
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
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 [...])
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
Concurrent Records with Async
fetchBob :: RecA IO [Name, Email Work]
bobConcurrently :: RecA Concurrently [Name, Email Work]
concurrentBob :: Concurrently (RecA Identity [...])
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])
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
Containers: The Syntax for Data Types
container : Type
U : Type ElU : U → Type
U ElU : container
Containers: The Syntax for Data Types
container : Type
U : Type ElU : U → Type
U ElU : container
C : container
C.Sh : Type
Containers: The Syntax for Data Types
container : Type
U : Type ElU : U → Type
U ElU : container
C : container
C.Sh : Type
C U ElU
C.Sh U
Containers: The Syntax for Data Types
container : Type
U : Type ElU : U → Type
U ElU : container
C : container
C.Sh : Type
C U ElU
C.Sh U
C : container
C.Po : C.Sh → Type
Containers: The Syntax for Data Types
container : Type
U : Type ElU : U → Type
U ElU : container
C : container
C.Sh : Type
C U ElU
C.Sh U
C : container
C.Po : C.Sh → Type
C U ElU
C.Po ElU
Restricting Containers
C : container V ⊆ C.Sh
C|V : container
Restricting Containers
C : container V ⊆ C.Sh
C|V : container
C U ElU
C|V V ElU |V
Container Lifting
C : container F : Type → Type
C ↑ F : container
Container Lifting
C : container F : Type → Type
C ↑ F : container
C U ElU
C ↑ F U F ◦ ElU
A Menagerie of Quantifiers
A Menagerie of Quantifiers
Dependent Products:
Γ A : Type Γ, x : A B : Type
Γ A B : Type
Γ, x : A e : B[x]
Γ λx.e : A B
A Menagerie of Quantifiers
Dependent Sums:
Γ A : Type Γ, x : A B : Type
Γ A B : Type
Γ a : A Γ b : B[a]
Γ a, b : A B
A Menagerie of Quantifiers
Inductive Types:
Γ A : Type Γ, x : A B : Type
Γ WA B : Type
Γ a : A Γ, v : B[a] b : WA B
Γ sup(a; v. b) : WA B
A Menagerie of Quantifiers
Coinductive Types:
Γ A : Type Γ, x : A B : Type
Γ MA B : Type
Γ a : A Γ, v : B[a] b : ∞ (MA B)
Γ inf(a; v. b) : MA B
A Scheme for Quantifiers
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
Quantifiers Give Containers Semantics
Γ, A : Type, (x : A B : Type) QAB : Type
Γ Q quantifier
C : container Q quantifier
C Q : Type
Quantifiers Give Containers Semantics
Γ, A : Type, (x : A B : Type) QAB : Type
Γ Q quantifier
C : container Q quantifier
C Q : Type
C U ElU
C Q QU ElU
Vinyl Records as Containers
Vinyl Records as Containers
Records and corecords are finite products and sums
respectively.
Vinyl Records as Containers
Records and corecords are finite products and sums
respectively.
Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π
Vinyl Records as Containers
Records and corecords are finite products and sums
respectively.
Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π
CoRec ElU F rs ∼= (U ElU )|rs − ↑ F Σ
Vinyl Records as Containers
Records and corecords are finite products and sums
respectively.
Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π
CoRec ElU F rs ∼= (U ElU )|rs − ↑ F Σ
??? ElU F rs ∼= (U ElU )|rs − ↑ F W
Vinyl Records as Containers
Records and corecords are finite products and sums
respectively.
Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π
CoRec ElU F rs ∼= (U ElU )|rs − ↑ F Σ
??? ElU F rs ∼= (U ElU )|rs − ↑ F W
??? ElU F rs ∼= (U ElU )|rs − ↑ F M
Questions

Programming in Vinyl (BayHac 2014)

  • 1.
    Programming in Vinyl JonSterling jonmsterling.com May 18, 2014
  • 2.
  • 3.
    Records in GHC7.8 Haskell records are nominally typed
  • 4.
    Records in GHC7.8 Haskell records are nominally typed They may not share field names
  • 5.
    Records in GHC7.8 Haskell records are nominally typed They may not share field names data R = R { x :: X }
  • 6.
    Records in GHC7.8 Haskell records are nominally typed They may not share field names data R = R { x :: X } data R’ = R’ { x :: X } −− ˆ Error
  • 7.
  • 8.
  • 9.
    Structural Typing Sharing fieldnames and accessors Record types may be characterized structurally
  • 10.
  • 11.
    Row Polymorphism How dowe express the type of a function which adds a field to a record?
  • 12.
    Row Polymorphism How dowe express the type of a function which adds a field to a record? x : {foo : A} f(x) : {foo : A, bar : B}
  • 13.
    Row Polymorphism How dowe express the type of a function which adds a field to a record? x : {foo : A; rs} f(x) : {foo : A, bar : B; rs}
  • 14.
    Roll Your Ownin Haskell
  • 15.
    Roll Your Ownin Haskell data (s :: Symbol) ::: (t :: ∗) = Field
  • 16.
    Roll Your Ownin Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where
  • 17.
    Roll Your Ownin Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where RNil :: Rec ’[]
  • 18.
    Roll Your Ownin Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where RNil :: Rec ’[] (:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
  • 19.
    Roll Your Ownin Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where RNil :: Rec ’[] (:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs) class s ∈ (rs :: [∗])
  • 20.
    Roll Your Ownin 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
  • 21.
    Roll Your Ownin 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]
  • 22.
    Roll Your Ownin 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)
  • 23.
    Roll Your Ownin 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
  • 24.
    Roll Your Ownin Haskell
  • 25.
    Roll Your Ownin Haskell f :: Rec (”foo” ::: A ’: rs) → Rec (”bar” ::: B ’: ”foo” ::: A ’: rs)
  • 26.
  • 27.
    Universes `a laTarski A type U of codes for types.
  • 28.
    Universes `a laTarski A type U of codes for types. Function ElU : U → Type.
  • 29.
    Universes `a laTarski A type U of codes for types. Function ElU : U → Type. Γ s : U Γ ElU (s) : Type
  • 30.
    Universes `a laTarski Type
  • 31.
    Universes `a laTarski  Type
  • 32.
    Universes `a laTarski  Type
  • 33.
    Universes `a laTarski  Type
  • 34.
  • 35.
    A Closed Universe LetA be a universe of address books:
  • 36.
    A Closed Universe LetA be a universe of address books: Statics:
  • 37.
    A Closed Universe LetA be a universe of address books: Statics: A : Type
  • 38.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type
  • 39.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label
  • 40.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A
  • 41.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A : Label Phone[ ], Email[ ] : A
  • 42.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A : Label Phone[ ], Email[ ] : A s : A ElA(s) : Type
  • 43.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A : Label Phone[ ], Email[ ] : A s : A ElA(s) : Type Dynamics:
  • 44.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A : Label Phone[ ], Email[ ] : A s : A ElA(s) : Type Dynamics: ElA(Name) string
  • 45.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A : Label Phone[ ], Email[ ] : A s : A ElA(s) : Type Dynamics: ElA(Name) string ElA(Email[ ]) string
  • 46.
    A Closed Universe LetA be a universe of address books: Statics: A : Type Label : Type Home, Office : Label Name : A : Label Phone[ ], Email[ ] : A s : A ElA(s) : Type Dynamics: ElA(Name) string ElA(Email[ ]) string ElA(Phone[ ]) list(N)
  • 47.
  • 48.
    Records as Products Records:the product of the image of ElU in Type restricted to a subset of U.
  • 49.
    Records as Products Records:the product of the image of ElU in Type restricted to a subset of U. recordU V⊆U V ElU |V
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
    Example Record recordU V⊆U V ElU|V A {Name, Email Work}
  • 55.
    Example Record recordU V⊆U V ElU|V A {Name, Email Work} ex : recordU
  • 56.
    Example Record recordU V⊆U V ElU|V A {Name, Email Work} ex : recordU ex A , λ. {Name → ”Robert Harper”; Email Work → ”rwh@cs.cmu.edu”}
  • 57.
  • 58.
    Presheaves A presheaf onsome space X is a functor O(X)op → Type, where O is the category of open sets of X for whatever topology you have chosen.
  • 59.
  • 60.
    Topologies on somespace X What are the open sets on X?
  • 61.
    Topologies on somespace X What are the open sets on X? The empty set and X are open sets The union of open sets is open Finite intersections of open sets are open
  • 62.
  • 63.
    Records are Presheaves LetO = P, the discrete topology
  • 64.
    Records are Presheaves LetO = P, the discrete topology Then records on a universe X give rise to a presheaf R: subset inclusions are taken to casts from larger to smaller records
  • 65.
    Records are Presheaves LetO = P, the discrete topology Then records on a universe X give rise to a presheaf R: subset inclusions are taken to casts from larger to smaller records for V ⊆ X R(V ) :≡ V ElX|V : Type
  • 66.
    Records are Presheaves LetO = P, the discrete topology Then records on a universe X give rise to a presheaf R: subset inclusions are taken to casts from larger to smaller records for V ⊆ X R(V ) :≡ V ElX|V : Type for i : V → U R(i) :≡ cast : R(U) → R(V )
  • 67.
  • 68.
    Records are Sheaves Fora cover U = i Ui on X, then: R(U) i R(Ui) i,j R(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))
  • 69.
    Records are Sheaves Fora cover U = i Ui on X, then: R(U) i R(Ui) i,j R(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))
  • 70.
  • 71.
    Corecords as Sums Corecords(extensible variants): the sum of the image of ElU in Type restricted to a subset of U.
  • 72.
    Corecords as Sums Corecords(extensible variants): the sum of the image of ElU in Type restricted to a subset of U. corecordU V⊆U V ElU |V
  • 73.
  • 74.
  • 75.
  • 76.
    Doing it inHaskell
  • 77.
    Doing it inHaskell Create a universe U at the type-level
  • 78.
    Doing it inHaskell Create a universe U at the type-level Use type families to approximate ElU
  • 79.
    Doing it inHaskell Create a universe U at the type-level Use type families to approximate ElU Parameterize Rec by U, ElU ?
  • 80.
  • 81.
    Records in Haskell dataRec :: (U → ∗) → [ U ] → ∗ where
  • 82.
    Records in Haskell dataRec :: (U → ∗) → [ U ] → ∗ where RNil :: Rec elU ’[]
  • 83.
    Records in Haskell dataRec :: (U → ∗) → [ U ] → ∗ where RNil :: Rec elU ’[] (:&) :: !(elU r) → !(Rec elU rs) → Rec elU (r ’: rs)
  • 84.
  • 85.
    Records in Haskell(Actually) data TyFun :: ∗ → ∗ → ∗
  • 86.
    Records in Haskell(Actually) data TyFun :: ∗ → ∗ → ∗ type family (f :: TyFun k l → ∗) $ (x :: k) :: l
  • 87.
    Records in Haskell(Actually) data TyFun :: ∗ → ∗ → ∗ type family (f :: TyFun k l → ∗) $ (x :: k) :: l data Rec :: (TyFun U ∗ → ∗) → [ U ] → ∗ where RNil :: Rec elU ’[] (:&) :: !(elU $ r) → !(Rec elU rs) → Rec elU (r ’: rs)
  • 88.
  • 89.
    Recovering HList data Id:: (TyFun k k) → ∗ where type instance Id $ x = x
  • 90.
    Recovering HList data Id:: (TyFun k k) → ∗ where type instance Id $ x = x type HList rs = Rec Id rs
  • 91.
    Recovering HList data Id:: (TyFun k k) → ∗ where type instance Id $ x = x type HList rs = Rec Id rs ex :: HList [Z, Bool, String]
  • 92.
    Recovering HList data Id:: (TyFun k k) → ∗ where type instance Id $ x = x type HList rs = Rec Id rs ex :: HList [Z, Bool, String] ex = 34 :& True :& ”vinyl” :& RNil
  • 93.
    Validating Records bob ::Rec ElA [Name, Email Work]
  • 94.
    Validating Records bob ::Rec ElA [Name, Email Work] bob = Name =: ”Robert Harper” ⊕ Email Work =: ”rwh@cs.cmu.edu”
  • 95.
    Validating Records bob ::Rec ElA [Name, Email Work] bob = Name =: ”Robert Harper” ⊕ Email Work =: ”rwh@cs.cmu.edu” validateName :: String → Either Error String validateEmail :: String → Either Error String validatePhone :: [N] → Either Error [N]
  • 96.
    Validating Records bob ::Rec ElA [Name, Email Work] bob = Name =: ”Robert Harper” ⊕ Email Work =: ”rwh@cs.cmu.edu” validateName :: String → Either Error String validateEmail :: String → Either Error String validatePhone :: [N] → Either Error [N] *unnnnnhhh...*
  • 97.
    Validating Records bob ::Rec ElA [Name, Email Work] bob = Name =: ”Robert Harper” ⊕ Email Work =: ”rwh@cs.cmu.edu” validateName :: String → Either Error String validateEmail :: String → Either Error String validatePhone :: [N] → Either Error [N] *unnnnnhhh...* validateContact :: Rec ElA [Name, Email Work] → Either Error (Rec ElA [Name, Email Work])
  • 98.
  • 99.
    Effects inside records dataRec :: (TyFun U ∗ → ∗) → [ U ] → ∗ where RNil :: Rec elU ’[] (:&) :: !(elU $ r) → !(Rec elU rs) → Rec elU (r ’: rs)
  • 100.
    Effects inside records dataRec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where RNil :: Rec elU f ’[] (:&) :: !(f (elU $ r)) → !(Rec elU f rs) → Rec elU f (r ’: rs)
  • 101.
    Effects inside records dataRec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where RNil :: 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]
  • 102.
    Effects inside records dataRec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where RNil :: 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
  • 103.
    Effects inside records dataRec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where RNil :: 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]
  • 104.
    Effects inside records dataRec :: (TyFun U ∗ → ∗) → (∗ → ∗) → [ U ] → ∗ where RNil :: 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
  • 105.
  • 106.
    Compositional Validation type RecA= Rec ElA bob :: RecA Identity [Name, Email Work]
  • 107.
    Compositional Validation type RecA= Rec ElA bob :: RecA Identity [Name, Email Work] bob = Name =: ”Robert Harper” ⊕ Email Work =: ”rwh@cs.cmu.edu”
  • 108.
    Compositional Validation type RecA= Rec ElA bob :: RecA Identity [Name, Email Work] bob = Name =: ”Robert Harper” ⊕ Email Work =: ”rwh@cs.cmu.edu”
  • 109.
  • 110.
    Compositional Validation type Validatora = a → Either Error a validateName :: RecA Validator ’[Name] validatePhone :: ∀ . RecA Validator ’[Phone ] validateEmail :: ∀ . RecA Validator ’[Email ]
  • 111.
    Compositional Validation type Validatora = 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 ]
  • 112.
    Compositional Validation type Validatora = 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 TotalContact validateContact = validateName ⊕ validateEmail ⊕ validateEmail ⊕ validatePhone ⊕ validatePhone
  • 113.
  • 114.
    Record Operators newtype Lifto f g x = Lift { runLift :: f x ‘o‘ g x }
  • 115.
    Record Operators newtype Lifto f g x = Lift { runLift :: f x ‘o‘ g x } type Validator = Lift (→) Identity (Either Error)
  • 116.
    Record Operators newtype Lifto 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
  • 117.
    Record Operators newtype Lifto 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)
  • 118.
    Compositional Validation newtype Lifto 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)
  • 119.
    Compositional Validation newtype Lifto 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) validateContact :: RecA Validator TotalContact
  • 120.
    Compositional Validation newtype Lifto 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) validateContact :: RecA Validator TotalContact bobValid :: RecA (Either Error) [Name, Email Work]
  • 121.
    Compositional Validation newtype Lifto 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) validateContact :: RecA Validator TotalContact bobValid :: RecA (Either Error) [Name, Email Work] bobValid = cast validateContact bob
  • 122.
    Compositional Validation newtype Lifto 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) validateContact :: RecA Validator TotalContact bobValid :: RecA (Either Error) [Name, Email Work] bobValid = cast validateContact bob validBob :: Either Error (RecA Identity [Name, Email Work])
  • 123.
    Compositional Validation newtype Lifto 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) 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
  • 124.
  • 125.
    Laziness as aneffect newtype Identity a = Identity { runIdentity :: a }
  • 126.
    Laziness as aneffect newtype Identity a = Identity { runIdentity :: a } data Thunk a = Thunk { unThunk :: a }
  • 127.
    Laziness as aneffect newtype Identity a = Identity { runIdentity :: a } data Thunk a = Thunk { unThunk :: a } type PlainRecU rs = RecU Identity rs
  • 128.
    Laziness as aneffect newtype Identity a = Identity { runIdentity :: a } data Thunk a = Thunk { unThunk :: a } type PlainRecU rs = RecU Identity rs type LazyRecU rs = RecU Thunk rs
  • 129.
  • 130.
    Concurrent Records withAsync fetchName :: RecA IO ’[Name]
  • 131.
    Concurrent Records withAsync fetchName :: RecA IO ’[Name] fetchName = Name ⇐ someOperation
  • 132.
    Concurrent Records withAsync fetchName :: RecA IO ’[Name] fetchName = Name ⇐ someOperation fetchWorkEmail :: RecA IO ’[Email Work]
  • 133.
    Concurrent Records withAsync fetchName :: RecA IO ’[Name] fetchName = Name ⇐ someOperation fetchWorkEmail :: RecA IO ’[Email Work] fetchWorkEmail = Email Work ⇐ anotherOperation
  • 134.
    Concurrent Records withAsync fetchName :: RecA IO ’[Name] fetchName = Name ⇐ someOperation fetchWorkEmail :: RecA IO ’[Email Work] fetchWorkEmail = Email Work ⇐ anotherOperation fetchBob :: RecA IO [Name, Email Work]
  • 135.
    Concurrent Records withAsync 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
  • 136.
  • 137.
    Concurrent Records withAsync newtype Concurrently a = Concurrently { runConcurrently :: IO a }
  • 138.
    Concurrent Records withAsync newtype Concurrently a = Concurrently { runConcurrently :: IO a } ( $ ) :: (∀ a. f a → g a) → RecU f rs → RecU g rs
  • 139.
    Concurrent Records withAsync newtype Concurrently a = Concurrently { runConcurrently :: IO a } ( $ ) :: (∀ a. f a → g a) → RecU f rs → RecU g rs bobConcurrently :: RecA Concurrently [Name, Email Work]
  • 140.
    Concurrent Records withAsync 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
  • 141.
    Concurrent Records withAsync 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 [...])
  • 142.
    Concurrent Records withAsync 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
  • 143.
  • 144.
    Concurrent Records withAsync fetchBob :: RecA IO [Name, Email Work] bobConcurrently :: RecA Concurrently [Name, Email Work] concurrentBob :: Concurrently (RecA Identity [...])
  • 145.
    Concurrent Records withAsync fetchBob :: RecA IO [Name, Email Work] bobConcurrently :: RecA Concurrently [Name, Email Work] concurrentBob :: Concurrently (RecA Identity [...]) bob :: IO (RecA Identity [Name, Email Work])
  • 146.
    Concurrent Records withAsync 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
  • 147.
    Containers: The Syntaxfor Data Types container : Type
  • 148.
    Containers: The Syntaxfor Data Types container : Type U : Type ElU : U → Type U ElU : container
  • 149.
    Containers: The Syntaxfor Data Types container : Type U : Type ElU : U → Type U ElU : container C : container C.Sh : Type
  • 150.
    Containers: The Syntaxfor Data Types container : Type U : Type ElU : U → Type U ElU : container C : container C.Sh : Type C U ElU C.Sh U
  • 151.
    Containers: The Syntaxfor Data Types container : Type U : Type ElU : U → Type U ElU : container C : container C.Sh : Type C U ElU C.Sh U C : container C.Po : C.Sh → Type
  • 152.
    Containers: The Syntaxfor Data Types container : Type U : Type ElU : U → Type U ElU : container C : container C.Sh : Type C U ElU C.Sh U C : container C.Po : C.Sh → Type C U ElU C.Po ElU
  • 153.
    Restricting Containers C :container V ⊆ C.Sh C|V : container
  • 154.
    Restricting Containers C :container V ⊆ C.Sh C|V : container C U ElU C|V V ElU |V
  • 155.
    Container Lifting C :container F : Type → Type C ↑ F : container
  • 156.
    Container Lifting C :container F : Type → Type C ↑ F : container C U ElU C ↑ F U F ◦ ElU
  • 157.
    A Menagerie ofQuantifiers
  • 158.
    A Menagerie ofQuantifiers Dependent Products: Γ A : Type Γ, x : A B : Type Γ A B : Type Γ, x : A e : B[x] Γ λx.e : A B
  • 159.
    A Menagerie ofQuantifiers Dependent Sums: Γ A : Type Γ, x : A B : Type Γ A B : Type Γ a : A Γ b : B[a] Γ a, b : A B
  • 160.
    A Menagerie ofQuantifiers Inductive Types: Γ A : Type Γ, x : A B : Type Γ WA B : Type Γ a : A Γ, v : B[a] b : WA B Γ sup(a; v. b) : WA B
  • 161.
    A Menagerie ofQuantifiers Coinductive Types: Γ A : Type Γ, x : A B : Type Γ MA B : Type Γ a : A Γ, v : B[a] b : ∞ (MA B) Γ inf(a; v. b) : MA B
  • 162.
    A Scheme forQuantifiers
  • 163.
    A Scheme forQuantifiers Γ, A : Type, (x : A B : Type) QAB : Type Γ Q quantifier
  • 164.
    Quantifiers Give ContainersSemantics Γ, A : Type, (x : A B : Type) QAB : Type Γ Q quantifier
  • 165.
    Quantifiers Give ContainersSemantics Γ, A : Type, (x : A B : Type) QAB : Type Γ Q quantifier C : container Q quantifier C Q : Type
  • 166.
    Quantifiers Give ContainersSemantics Γ, A : Type, (x : A B : Type) QAB : Type Γ Q quantifier C : container Q quantifier C Q : Type C U ElU C Q QU ElU
  • 167.
    Vinyl Records asContainers
  • 168.
    Vinyl Records asContainers Records and corecords are finite products and sums respectively.
  • 169.
    Vinyl Records asContainers Records and corecords are finite products and sums respectively. Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π
  • 170.
    Vinyl Records asContainers Records and corecords are finite products and sums respectively. Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π CoRec ElU F rs ∼= (U ElU )|rs − ↑ F Σ
  • 171.
    Vinyl Records asContainers Records and corecords are finite products and sums respectively. Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π CoRec ElU F rs ∼= (U ElU )|rs − ↑ F Σ ??? ElU F rs ∼= (U ElU )|rs − ↑ F W
  • 172.
    Vinyl Records asContainers Records and corecords are finite products and sums respectively. Rec ElU F rs ∼= (U ElU )|rs − ↑ F Π CoRec ElU F rs ∼= (U ElU )|rs − ↑ F Σ ??? ElU F rs ∼= (U ElU )|rs − ↑ F W ??? ElU F rs ∼= (U ElU )|rs − ↑ F M
  • 173.