SlideShare a Scribd company logo
1 of 136
Download to read offline
Vinyl: Records in Haskell
and Type Theory
Jon Sterling
jonmsterling.com
August 12, 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)
Why be stringly typed?
Why be stringly typed?
Let’s generalize our key space
Old
We relied on a single representation for keys as pairs of
strings and types.
data Rec :: [∗] → ∗ where
RNil :: Rec ’[]
(:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
Proposed
We put the keys in an arbitrary type (kind) and describe
their semantics with a function el (for elements).
data Rec :: [∗] → ∗ where
RNil :: Rec ’[]
(:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
Proposed
We put the keys in an arbitrary type (kind) and describe
their semantics with a function el (for elements).
data Rec :: (el :: k → ∗) → (rs :: [k]) → ∗ where
RNil :: Rec el ’[]
(:&) :: ∀(r :: k) (rs’:: [k]). !(el r) → !(Rec el rs) → Rec (r ’: rs’)
Proposed
We put the keys in an arbitrary type (kind) and describe
their semantics with a function el (for elements).
data Rec :: (k → ∗) → [k] → ∗ where
RNil :: Rec el ’[]
(:&) :: !(el r) → !(Rec el rs) → Rec (r ’: rs)
Actual
Type families are not functions, but in many cases can
simulate them using Richard Eisenberg’s technique
outlined in Defunctionalization for the win.
data TyFun :: ∗ → ∗ → ∗
Actual
Type families are not functions, but in many cases can
simulate them using Richard Eisenberg’s technique
outlined in Defunctionalization for the win.
data TyFun :: ∗ → ∗ → ∗
type family (f :: TyFun k l → ∗) $ (x :: k) :: l
Actual
Type families are not functions, but in many cases can
simulate them using Richard Eisenberg’s technique
outlined in Defunctionalization for the win.
data TyFun :: ∗ → ∗ → ∗
type family (f :: TyFun k l → ∗) $ (x :: k) :: l
data Rec :: (TyFun k ∗ → ∗) → [k] → ∗ where
RNil :: Rec el ’[]
(:&) :: !(el $ r) → !(Rec el rs) → Rec el (r ’: rs)
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
data SLabel :: Label → ∗ where
SHome :: SLabel Home
SWork :: SLabel Work
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
data SLabel :: Label → ∗
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
data SLabel :: Label → ∗
data SAddrKeys :: AddrKeys → ∗ where
SName :: SAddrKeys Name
SPhone :: SLabel l → SAddrKeys (Phone l)
SEmail :: SLabel l → SAddrKeys (Email l)
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
data SLabel :: Label → ∗
data SAddrKeys :: AddrKeys → ∗
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
data SLabel :: Label → ∗
data SAddrKeys :: AddrKeys → ∗
data ElAddr :: (TyFun AddrKeys ∗) → ∗ where
ElAddr :: ElAddr el
Example
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
data SLabel :: Label → ∗
data SAddrKeys :: AddrKeys → ∗
data ElAddr :: (TyFun AddrKeys ∗) → ∗ where
ElAddr :: ElAddr el
type instance ElAddr $ Name = String
type instance ElAddr $ (Phone l) = [N]
type instance ElAddr $ (Email l) = String
type AddrRec rs = Rec ElAddr rs
Sugared example
import Data.Singletons as S
Sugared example
import Data.Singletons as S
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
S.genSingletons [ ’’Label, ’’AddrKeys ]
Sugared example
import Data.Singletons as S
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
S.genSingletons [ ’’Label, ’’AddrKeys ]
makeUniverse ’’AddrKeys ”ElAddr”
Sugared example
import Data.Singletons as S
data Label = Home | Work
data AddrKeys = Name | Phone Label | Email Label
S.genSingletons [ ’’Label, ’’AddrKeys ]
makeUniverse ’’AddrKeys ”ElAddr”
type instance ElAddr $ Name = String
type instance ElAddr $ (Phone l) = [N]
type instance ElAddr $ (Email l) = String
type AddrRec rs = Rec ElAddr rs
Example records
bob :: AddrRec [Name, Email Work]
bob = SName =: ”Robert W. Harper”
⊕ SEmail SWork =: ”rwh@cs.cmu.edu”
Example records
bob :: AddrRec [Name, Email Work]
bob = SName =: ”Robert W. Harper”
⊕ SEmail SWork =: ”rwh@cs.cmu.edu”
jon :: AddrRec [Name, Email Work, Email Home]
jon = SName =: ”Jon M. Sterling”
⊕ SEmail SWork =: ”jon@fobo.net”
⊕ SEmail SHome =: ”jon@jonmsterling.com”
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]
ex = 34 :& True :& ”vinyl” :& RNil
Validating records
validateName :: String → Either Error String
validateEmail :: String → Either Error String
validatePhone :: [N] → Either Error [N]
Validating records
validateName :: String → Either Error String
validateEmail :: String → Either Error String
validatePhone :: [N] → Either Error [N]
*unnnnnhhh...*
Validating records
validateName :: String → Either Error String
validateEmail :: String → Either Error String
validatePhone :: [N] → Either Error [N]
*unnnnnhhh...*
validateContact
:: AddrRec [Name, Email Work]
→ Either Error (AddrRec [Name, Email Work])
Welp.
Effects inside records
data Rec :: (TyFun k ∗ → ∗) → [k] → ∗ where
RNil :: Rec el ’[]
(:&) :: !(el $ r) → !(Rec el rs) → Rec el (r ’: rs)
Effects inside records
data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where
RNil :: Rec el f ’[]
(:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs)
Effects inside records
data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where
RNil :: Rec el f ’[]
(:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs)
Effects inside records
data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where
RNil :: Rec el f ’[]
(:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs)
(=:) : Applicative f ⇒ sing r → el $ r → Rec el f ’[r]
k =: x = pure x :& RNil
Effects inside records
data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where
RNil :: Rec el f ’[]
(:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs)
(=:) : Applicative f ⇒ sing r → el $ r → Rec el f ’[r]
k =: x = pure x :& RNil
(⇐): sing r → f (el $ r) → Rec el f ’[r]
k ⇐ x = x :& RNil
Compositional validation
type Validator a = a → Either Error a
Compositional validation
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
type Validator = Lift (→) Identity (Either Error)
Compositional validation
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
type Validator = Lift (→) Identity (Either Error)
Compositional validation
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
type Validator = Lift (→) Identity (Either Error)
validateName :: AddrRec Validator ’[Name]
validatePhone :: ∀l. AddrRec Validator ’[Phone l]
validateEmail :: ∀l. AddrRec Validator ’[Email l]
Compositional validation
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
type Validator = Lift (→) Identity (Either Error)
validateName :: AddrRec Validator ’[Name]
validatePhone :: ∀l. AddrRec Validator ’[Phone l]
validateEmail :: ∀l. AddrRec Validator ’[Email l]
type TotalContact =
[ Name, Email Home, Email Work
, Phone Home, Phone Work ]
Compositional validation
newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x }
type Validator = Lift (→) Identity (Either Error)
validateName :: AddrRec Validator ’[Name]
validatePhone :: ∀l. AddrRec Validator ’[Phone l]
validateEmail :: ∀l. AddrRec Validator ’[Email l]
type TotalContact =
[ Name, Email Home, Email Work
, Phone Home, Phone Work ]
validateContact :: AddrRec Validator TotalContact
validateContact = validateName
⊕ validateEmail ⊕ validateEmail
⊕ validatePhone ⊕ validatePhone
Record effect operators
Record effect operators
( ) :: Rec el (Lift (→) f g) rs → Rec el f rs → Rec el g rs
Record effect operators
( ) :: Rec el (Lift (→) f g) rs → Rec el f rs → Rec el g rs
rtraverse :: Applicative h ⇒
(∀ x. f x → h (g x)) →
Rec el f rs → h (Rec el g rs)
Record effect operators
( ) :: Rec el (Lift (→) f g) rs → Rec el f rs → Rec el g rs
rtraverse :: Applicative h ⇒
(∀ x. f x → h (g x)) →
Rec el f rs → h (Rec el g rs)
rdist :: Applicative f ⇒ Rec el f rs → f (Rec el Identity rs)
rdist = rtraverse (fmap Identity)
Compositional validation
bob :: AddrRec [Name, Email Work]
validateContact :: AddrRec Validator TotalContact
Compositional validation
bob :: AddrRec [Name, Email Work]
validateContact :: AddrRec Validator TotalContact
bobValid :: AddrRec (Either Error) [Name, Email Work]
bobValid = cast validateContact bob
Compositional validation
bob :: AddrRec [Name, Email Work]
validateContact :: AddrRec Validator TotalContact
bobValid :: AddrRec (Either Error) [Name, Email Work]
bobValid = cast validateContact bob
validBob :: Either Error (AddrRec Identity [Name, Email Work])
validBob = rdist bobValid
Laziness as an effect
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 PlainRec el rs = Rec el Identity rs
Laziness as an effect
newtype Identity a = Identity { runIdentity :: a }
data Thunk a = Thunk { unThunk :: a }
type PlainRec el rs = Rec el Identity rs
type LazyRec el rs = Rec el Thunk rs
Concurrent records with Async
Concurrent records with Async
fetchName :: AddrRec IO ’[Name]
fetchName = SName ⇐ runDB nameQuery
Concurrent records with Async
fetchName :: AddrRec IO ’[Name]
fetchName = SName ⇐ runDB nameQuery
fetchWorkEmail :: AddrRec IO ’[Email Work]
fetchWorkEmail = SEmail SWork ⇐ runDB emailQuery
Concurrent records with Async
fetchName :: AddrRec IO ’[Name]
fetchName = SName ⇐ runDB nameQuery
fetchWorkEmail :: AddrRec IO ’[Email Work]
fetchWorkEmail = SEmail SWork ⇐ runDB emailQuery
fetchBob :: AddrRec 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) → Rec el f rs → Rec el g rs
Concurrent records with Async
newtype Concurrently a
= Concurrently { runConcurrently :: IO a }
( $ ) :: (∀ a. f a → g a) → Rec el f rs → Rec el g rs
bobConcurrently :: Rec el Concurrently [Name, Email Work]
bobConcurrently = Concurrently $ fetchBob
Concurrent records with Async
newtype Concurrently a
= Concurrently { runConcurrently :: IO a }
( $ ) :: (∀ a. f a → g a) → Rec el f rs → Rec el g rs
bobConcurrently :: Rec el Concurrently [Name, Email Work]
bobConcurrently = Concurrently $ fetchBob
concurrentBob :: IO (PlainRec el [Name, Email Work])
concurrentBob = runConcurrently (rdist bobConcurrently)
Type Theoretic Semantics for Records
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
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

Type
Records as products

Type
×
×
×
×
Vinyl: beyond records?
Vinyl: beyond records?
Records and corecords are finite products and sums
respectively.
Vinyl: beyond records?
Records and corecords are finite products and sums
respectively.
Rec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
Vinyl: beyond records?
Records and corecords are finite products and sums
respectively.
Rec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
CoRec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
Vinyl: beyond records?
Records and corecords are finite products and sums
respectively.
Rec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
CoRec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
Data(ElU ; F; rs) :≡ WU|rs
F ◦ ElU
Vinyl: beyond records?
Records and corecords are finite products and sums
respectively.
Rec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
CoRec(ElU ; F; rs) :≡
U|rs
F ◦ ElU
Data(ElU ; F; rs) :≡ WU|rs
F ◦ ElU
Codata(ElU ; F; rs) :≡ MU|rs
F ◦ ElU
Vinyl: beyond records?
(U|rs) (F ◦ ElU )
Vinyl: beyond records?
(U|rs) (F ◦ ElU ) Π
Vinyl: beyond records?
(U|rs) (F ◦ ElU ) W
Vinyl: beyond records?
(U|rs) (F ◦ ElU ) M
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
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
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 U ∈ P(X) R(U) :≡
U
ElX|U : 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 U ∈ P(X) R(U) :≡
U
ElX|U : 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))
Records with non-trivial topology
Records with non-trivial topology
NameType :≡ {F, M, L}
Records with non-trivial topology
NameType :≡ {F, M, L}
A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label}
Records with non-trivial topology
NameType :≡ {F, M, L}
A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label}
ElA :≡ λ .String
Records with non-trivial topology
NameType :≡ {F, M, L}
A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label}
ElA :≡ λ .String
T :≡ {U ∈ P(A) | Name[M] ∈ U
⇒ {Name[F], Name[L]} ⊆ U}
Records with non-trivial topology
NameType :≡ {F, M, L}
A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label}
ElA :≡ λ .String
T :≡ {U ∈ P(A) | Name[M] ∈ U
⇒ {Name[F], Name[L]} ⊆ U}
ex : RT ({Name[t] | t ∈ NameType})
ex :≡ {Name[F] → ”Robert”;
Name[M] → ”W”;
Name[L] → ”Harper”}
Records with non-trivial topology
NameType :≡ {F, M, L}
A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label}
ElA :≡ λ .String
T :≡ {U ∈ P(A) | Name[M] ∈ U
⇒ {Name[F], Name[L]} ⊆ U}
ex : RT ({Name[t] | t ∈ NameType})
ex :≡ {Name[F] → ”Robert”;
Name[M] → ”W”;
Name[L] → ”Harper”}
nope : RT ({Name[M], Phone[Work]})
nope :≡ {Name[M] → ”W”;
Phone[Work] → ”5555555555”}
Future work
Future work
Complete: formalization of records with topologies as
presheaves in Coq
Future work
Complete: formalization of records with topologies as
presheaves in Coq
In Progress: formalization of records as sheaves
Future work
Complete: formalization of records with topologies as
presheaves in Coq
In Progress: formalization of records as sheaves
Future: extension to dependent records using
extensional type theory and realizability (Nuprl,
MetaPRL)
Questions

More Related Content

What's hot

Why Haskell Matters
Why Haskell MattersWhy Haskell Matters
Why Haskell Mattersromanandreg
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
On Growth and Software
On Growth and SoftwareOn Growth and Software
On Growth and SoftwareCarlo Pescio
 
The elements of a functional mindset
The elements of a functional mindsetThe elements of a functional mindset
The elements of a functional mindsetEric Normand
 
Ozma: Extending Scala with Oz concurrency
Ozma: Extending Scala with Oz concurrencyOzma: Extending Scala with Oz concurrency
Ozma: Extending Scala with Oz concurrencyBeScala
 
Scala the language matters
Scala the language mattersScala the language matters
Scala the language mattersXiaojun REN
 
Lambda Expressions in Java 8
Lambda Expressions in Java 8Lambda Expressions in Java 8
Lambda Expressions in Java 8bryanbibat
 
FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳Yuri Inoue
 
[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ
[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ
[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQProvectus
 

What's hot (20)

ScalaBlitz
ScalaBlitzScalaBlitz
ScalaBlitz
 
P3 2017 python_regexes
P3 2017 python_regexesP3 2017 python_regexes
P3 2017 python_regexes
 
Why Haskell Matters
Why Haskell MattersWhy Haskell Matters
Why Haskell Matters
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
Scala for Jedi
Scala for JediScala for Jedi
Scala for Jedi
 
ScalaMeter 2014
ScalaMeter 2014ScalaMeter 2014
ScalaMeter 2014
 
List out of lambda
List out of lambdaList out of lambda
List out of lambda
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
 
Scala Parallel Collections
Scala Parallel CollectionsScala Parallel Collections
Scala Parallel Collections
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
P2 2017 python_strings
P2 2017 python_stringsP2 2017 python_strings
P2 2017 python_strings
 
On Growth and Software
On Growth and SoftwareOn Growth and Software
On Growth and Software
 
The elements of a functional mindset
The elements of a functional mindsetThe elements of a functional mindset
The elements of a functional mindset
 
Ozma: Extending Scala with Oz concurrency
Ozma: Extending Scala with Oz concurrencyOzma: Extending Scala with Oz concurrency
Ozma: Extending Scala with Oz concurrency
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Scala the language matters
Scala the language mattersScala the language matters
Scala the language matters
 
Lambda Expressions in Java 8
Lambda Expressions in Java 8Lambda Expressions in Java 8
Lambda Expressions in Java 8
 
FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
 
[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ
[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ
[Expert Fridays] Александр Чичигин - Как перестать бояться и полюбить COQ
 

Viewers also liked

Ephraim Maduhu NKONYA " Exploiting provision of land economic productivity w...
Ephraim Maduhu NKONYA "  Exploiting provision of land economic productivity w...Ephraim Maduhu NKONYA "  Exploiting provision of land economic productivity w...
Ephraim Maduhu NKONYA " Exploiting provision of land economic productivity w...Global Risk Forum GRFDavos
 
Síntesis Curricular Alejandra torres
Síntesis Curricular Alejandra torresSíntesis Curricular Alejandra torres
Síntesis Curricular Alejandra torresGRIAL-UNA
 
Getting Things Done With Social Media
Getting Things Done With Social MediaGetting Things Done With Social Media
Getting Things Done With Social MediaAndy Theimer
 
Perfil Corporativo & Portafolio W360
Perfil Corporativo & Portafolio W360Perfil Corporativo & Portafolio W360
Perfil Corporativo & Portafolio W360Veronica Wheelock
 
Phone Apps... para el teléfono de escritorio
Phone Apps... para el teléfono de escritorioPhone Apps... para el teléfono de escritorio
Phone Apps... para el teléfono de escritorioPaloSanto Solutions
 
Eltern lehrer - schulerfolg
Eltern   lehrer - schulerfolgEltern   lehrer - schulerfolg
Eltern lehrer - schulerfolgLukas Brand
 
Corporate Magazine UNSERE KJF selection of articles 2009-2014
Corporate Magazine UNSERE KJF selection of articles 2009-2014Corporate Magazine UNSERE KJF selection of articles 2009-2014
Corporate Magazine UNSERE KJF selection of articles 2009-2014Dr. Götz-Dietrich Opitz
 
Analizador de espectro 1
Analizador de espectro 1Analizador de espectro 1
Analizador de espectro 1asaashasjja
 
Atividades impressas algebra_i
Atividades impressas algebra_iAtividades impressas algebra_i
Atividades impressas algebra_iFran Correa
 
Achieve Global España
Achieve Global EspañaAchieve Global España
Achieve Global EspañaJorge Ceballos
 
cirugia plastica, Cervicoplastia, rejuvenecimiento de cuello
cirugia plastica, Cervicoplastia, rejuvenecimiento de cuellocirugia plastica, Cervicoplastia, rejuvenecimiento de cuello
cirugia plastica, Cervicoplastia, rejuvenecimiento de cuelloMauricio Rodríguez Urrea
 
Klöckner & Co - German Investment Conference 2010
Klöckner & Co - German Investment Conference 2010Klöckner & Co - German Investment Conference 2010
Klöckner & Co - German Investment Conference 2010Klöckner & Co SE
 
Blended Learning Best Practices for Empowering Students and Educators
Blended Learning Best Practices for Empowering Students and EducatorsBlended Learning Best Practices for Empowering Students and Educators
Blended Learning Best Practices for Empowering Students and EducatorsDreamBox Learning
 
Tecnicas de correccion de de la presbicia
Tecnicas de correccion de de la presbicia Tecnicas de correccion de de la presbicia
Tecnicas de correccion de de la presbicia CLINICA REMENTERIA
 
Músculos de la masticación, mímica, nervio facial, arteria facial y faringe
Músculos de la masticación, mímica, nervio facial, arteria facial y faringeMúsculos de la masticación, mímica, nervio facial, arteria facial y faringe
Músculos de la masticación, mímica, nervio facial, arteria facial y faringeOmar Miranda García
 
Akta keterangan 1950 / Evidence Act
Akta keterangan 1950 / Evidence ActAkta keterangan 1950 / Evidence Act
Akta keterangan 1950 / Evidence ActFAROUQ
 
Subvenciones y ayudas
Subvenciones y ayudasSubvenciones y ayudas
Subvenciones y ayudasVicenta
 

Viewers also liked (20)

Ephraim Maduhu NKONYA " Exploiting provision of land economic productivity w...
Ephraim Maduhu NKONYA "  Exploiting provision of land economic productivity w...Ephraim Maduhu NKONYA "  Exploiting provision of land economic productivity w...
Ephraim Maduhu NKONYA " Exploiting provision of land economic productivity w...
 
Síntesis Curricular Alejandra torres
Síntesis Curricular Alejandra torresSíntesis Curricular Alejandra torres
Síntesis Curricular Alejandra torres
 
Getting Things Done With Social Media
Getting Things Done With Social MediaGetting Things Done With Social Media
Getting Things Done With Social Media
 
Perfil Corporativo & Portafolio W360
Perfil Corporativo & Portafolio W360Perfil Corporativo & Portafolio W360
Perfil Corporativo & Portafolio W360
 
Phone Apps... para el teléfono de escritorio
Phone Apps... para el teléfono de escritorioPhone Apps... para el teléfono de escritorio
Phone Apps... para el teléfono de escritorio
 
MSC Fantasia
MSC FantasiaMSC Fantasia
MSC Fantasia
 
Generali
GeneraliGenerali
Generali
 
Eltern lehrer - schulerfolg
Eltern   lehrer - schulerfolgEltern   lehrer - schulerfolg
Eltern lehrer - schulerfolg
 
Corporate Magazine UNSERE KJF selection of articles 2009-2014
Corporate Magazine UNSERE KJF selection of articles 2009-2014Corporate Magazine UNSERE KJF selection of articles 2009-2014
Corporate Magazine UNSERE KJF selection of articles 2009-2014
 
Analizador de espectro 1
Analizador de espectro 1Analizador de espectro 1
Analizador de espectro 1
 
Atividades impressas algebra_i
Atividades impressas algebra_iAtividades impressas algebra_i
Atividades impressas algebra_i
 
Achieve Global España
Achieve Global EspañaAchieve Global España
Achieve Global España
 
cirugia plastica, Cervicoplastia, rejuvenecimiento de cuello
cirugia plastica, Cervicoplastia, rejuvenecimiento de cuellocirugia plastica, Cervicoplastia, rejuvenecimiento de cuello
cirugia plastica, Cervicoplastia, rejuvenecimiento de cuello
 
Klöckner & Co - German Investment Conference 2010
Klöckner & Co - German Investment Conference 2010Klöckner & Co - German Investment Conference 2010
Klöckner & Co - German Investment Conference 2010
 
Blended Learning Best Practices for Empowering Students and Educators
Blended Learning Best Practices for Empowering Students and EducatorsBlended Learning Best Practices for Empowering Students and Educators
Blended Learning Best Practices for Empowering Students and Educators
 
Mrinal_132996807
Mrinal_132996807Mrinal_132996807
Mrinal_132996807
 
Tecnicas de correccion de de la presbicia
Tecnicas de correccion de de la presbicia Tecnicas de correccion de de la presbicia
Tecnicas de correccion de de la presbicia
 
Músculos de la masticación, mímica, nervio facial, arteria facial y faringe
Músculos de la masticación, mímica, nervio facial, arteria facial y faringeMúsculos de la masticación, mímica, nervio facial, arteria facial y faringe
Músculos de la masticación, mímica, nervio facial, arteria facial y faringe
 
Akta keterangan 1950 / Evidence Act
Akta keterangan 1950 / Evidence ActAkta keterangan 1950 / Evidence Act
Akta keterangan 1950 / Evidence Act
 
Subvenciones y ayudas
Subvenciones y ayudasSubvenciones y ayudas
Subvenciones y ayudas
 

Similar to Galois Tech Talk / Vinyl: Records in Haskell and Type Theory

Getting started - Warewolf Syntax
Getting started - Warewolf Syntax  Getting started - Warewolf Syntax
Getting started - Warewolf Syntax Carol Vanden Bussche
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009David Pollak
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...PROIDEA
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Pythonlearn-11-Regex.pptx
Pythonlearn-11-Regex.pptxPythonlearn-11-Regex.pptx
Pythonlearn-11-Regex.pptxDave Tan
 
Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWorkhorse Computing
 
Functional programming with_scala
Functional programming with_scalaFunctional programming with_scala
Functional programming with_scalaRaymond Tay
 
Haskell for Scala-ists
Haskell for Scala-istsHaskell for Scala-ists
Haskell for Scala-istschriseidhof
 
Lecture 4 - Comm Lab: Web @ ITP
Lecture 4 - Comm Lab: Web @ ITPLecture 4 - Comm Lab: Web @ ITP
Lecture 4 - Comm Lab: Web @ ITPyucefmerhi
 
The Ring programming language version 1.10 book - Part 31 of 212
The Ring programming language version 1.10 book - Part 31 of 212The Ring programming language version 1.10 book - Part 31 of 212
The Ring programming language version 1.10 book - Part 31 of 212Mahmoud Samir Fayed
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!priort
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Using Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneUsing Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneCarl Brown
 

Similar to Galois Tech Talk / Vinyl: Records in Haskell and Type Theory (20)

Getting started - Warewolf Syntax
Getting started - Warewolf Syntax  Getting started - Warewolf Syntax
Getting started - Warewolf Syntax
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Pythonlearn-11-Regex.pptx
Pythonlearn-11-Regex.pptxPythonlearn-11-Regex.pptx
Pythonlearn-11-Regex.pptx
 
Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
Functional programming with_scala
Functional programming with_scalaFunctional programming with_scala
Functional programming with_scala
 
Haskell for Scala-ists
Haskell for Scala-istsHaskell for Scala-ists
Haskell for Scala-ists
 
First steps in PERL
First steps in PERLFirst steps in PERL
First steps in PERL
 
Relational+algebra (1)
Relational+algebra (1)Relational+algebra (1)
Relational+algebra (1)
 
Lecture 4 - Comm Lab: Web @ ITP
Lecture 4 - Comm Lab: Web @ ITPLecture 4 - Comm Lab: Web @ ITP
Lecture 4 - Comm Lab: Web @ ITP
 
Python : Regular expressions
Python : Regular expressionsPython : Regular expressions
Python : Regular expressions
 
The Ring programming language version 1.10 book - Part 31 of 212
The Ring programming language version 1.10 book - Part 31 of 212The Ring programming language version 1.10 book - Part 31 of 212
The Ring programming language version 1.10 book - Part 31 of 212
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Using Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneUsing Regular Expressions and Staying Sane
Using Regular Expressions and Staying Sane
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
07.04 joins
07.04 joins07.04 joins
07.04 joins
 

Recently uploaded

Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 

Recently uploaded (20)

Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 

Galois Tech Talk / Vinyl: Records in Haskell and Type Theory

  • 1. Vinyl: Records in Haskell and Type Theory Jon Sterling jonmsterling.com August 12, 2014
  • 3. Records in GHC 7.8 Haskell records are nominally typed
  • 4. Records in GHC 7.8 Haskell records are nominally typed They may not share field names
  • 5. Records in GHC 7.8 Haskell records are nominally typed They may not share field names data R = R { x :: X }
  • 6. 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
  • 8. Structural typing Sharing field names and accessors
  • 9. Structural typing Sharing field names and accessors Record types may be characterized structurally
  • 11. Row polymorphism How do we express the type of a function which adds a field to a record?
  • 12. 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}
  • 13. 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}
  • 14. Roll your own in Haskell
  • 15. Roll your own in Haskell data (s :: Symbol) ::: (t :: ∗) = Field
  • 16. Roll your own in Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where
  • 17. Roll your own in Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where RNil :: Rec ’[]
  • 18. Roll your own in Haskell data (s :: Symbol) ::: (t :: ∗) = Field data Rec :: [∗] → ∗ where RNil :: Rec ’[] (:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
  • 19. 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 :: [∗])
  • 20. 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
  • 21. 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]
  • 22. 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)
  • 23. 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
  • 24. Roll your own in Haskell
  • 25. Roll your own in Haskell f :: Rec (”foo” ::: A ’: rs) → Rec (”bar” ::: B ’: ”foo” ::: A ’: rs)
  • 26. Why be stringly typed?
  • 27. Why be stringly typed? Let’s generalize our key space
  • 28. Old We relied on a single representation for keys as pairs of strings and types. data Rec :: [∗] → ∗ where RNil :: Rec ’[] (:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
  • 29. Proposed We put the keys in an arbitrary type (kind) and describe their semantics with a function el (for elements). data Rec :: [∗] → ∗ where RNil :: Rec ’[] (:&) :: !t → !(Rec rs) → Rec ((s ::: t) ’: rs)
  • 30. Proposed We put the keys in an arbitrary type (kind) and describe their semantics with a function el (for elements). data Rec :: (el :: k → ∗) → (rs :: [k]) → ∗ where RNil :: Rec el ’[] (:&) :: ∀(r :: k) (rs’:: [k]). !(el r) → !(Rec el rs) → Rec (r ’: rs’)
  • 31. Proposed We put the keys in an arbitrary type (kind) and describe their semantics with a function el (for elements). data Rec :: (k → ∗) → [k] → ∗ where RNil :: Rec el ’[] (:&) :: !(el r) → !(Rec el rs) → Rec (r ’: rs)
  • 32. Actual Type families are not functions, but in many cases can simulate them using Richard Eisenberg’s technique outlined in Defunctionalization for the win. data TyFun :: ∗ → ∗ → ∗
  • 33. Actual Type families are not functions, but in many cases can simulate them using Richard Eisenberg’s technique outlined in Defunctionalization for the win. data TyFun :: ∗ → ∗ → ∗ type family (f :: TyFun k l → ∗) $ (x :: k) :: l
  • 34. Actual Type families are not functions, but in many cases can simulate them using Richard Eisenberg’s technique outlined in Defunctionalization for the win. data TyFun :: ∗ → ∗ → ∗ type family (f :: TyFun k l → ∗) $ (x :: k) :: l data Rec :: (TyFun k ∗ → ∗) → [k] → ∗ where RNil :: Rec el ’[] (:&) :: !(el $ r) → !(Rec el rs) → Rec el (r ’: rs)
  • 35. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label
  • 36. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label data SLabel :: Label → ∗ where SHome :: SLabel Home SWork :: SLabel Work
  • 37. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label data SLabel :: Label → ∗
  • 38. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label data SLabel :: Label → ∗ data SAddrKeys :: AddrKeys → ∗ where SName :: SAddrKeys Name SPhone :: SLabel l → SAddrKeys (Phone l) SEmail :: SLabel l → SAddrKeys (Email l)
  • 39. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label data SLabel :: Label → ∗ data SAddrKeys :: AddrKeys → ∗
  • 40. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label data SLabel :: Label → ∗ data SAddrKeys :: AddrKeys → ∗ data ElAddr :: (TyFun AddrKeys ∗) → ∗ where ElAddr :: ElAddr el
  • 41. Example data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label data SLabel :: Label → ∗ data SAddrKeys :: AddrKeys → ∗ data ElAddr :: (TyFun AddrKeys ∗) → ∗ where ElAddr :: ElAddr el type instance ElAddr $ Name = String type instance ElAddr $ (Phone l) = [N] type instance ElAddr $ (Email l) = String type AddrRec rs = Rec ElAddr rs
  • 43. Sugared example import Data.Singletons as S data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label S.genSingletons [ ’’Label, ’’AddrKeys ]
  • 44. Sugared example import Data.Singletons as S data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label S.genSingletons [ ’’Label, ’’AddrKeys ] makeUniverse ’’AddrKeys ”ElAddr”
  • 45. Sugared example import Data.Singletons as S data Label = Home | Work data AddrKeys = Name | Phone Label | Email Label S.genSingletons [ ’’Label, ’’AddrKeys ] makeUniverse ’’AddrKeys ”ElAddr” type instance ElAddr $ Name = String type instance ElAddr $ (Phone l) = [N] type instance ElAddr $ (Email l) = String type AddrRec rs = Rec ElAddr rs
  • 46. Example records bob :: AddrRec [Name, Email Work] bob = SName =: ”Robert W. Harper” ⊕ SEmail SWork =: ”rwh@cs.cmu.edu”
  • 47. Example records bob :: AddrRec [Name, Email Work] bob = SName =: ”Robert W. Harper” ⊕ SEmail SWork =: ”rwh@cs.cmu.edu” jon :: AddrRec [Name, Email Work, Email Home] jon = SName =: ”Jon M. Sterling” ⊕ SEmail SWork =: ”jon@fobo.net” ⊕ SEmail SHome =: ”jon@jonmsterling.com”
  • 49. Recovering HList data Id :: (TyFun k k) → ∗ where type instance Id $ x = x
  • 50. Recovering HList data Id :: (TyFun k k) → ∗ where type instance Id $ x = x type HList rs = Rec Id rs
  • 51. 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
  • 52. Validating records validateName :: String → Either Error String validateEmail :: String → Either Error String validatePhone :: [N] → Either Error [N]
  • 53. Validating records validateName :: String → Either Error String validateEmail :: String → Either Error String validatePhone :: [N] → Either Error [N] *unnnnnhhh...*
  • 54. Validating records validateName :: String → Either Error String validateEmail :: String → Either Error String validatePhone :: [N] → Either Error [N] *unnnnnhhh...* validateContact :: AddrRec [Name, Email Work] → Either Error (AddrRec [Name, Email Work])
  • 55. Welp.
  • 56. Effects inside records data Rec :: (TyFun k ∗ → ∗) → [k] → ∗ where RNil :: Rec el ’[] (:&) :: !(el $ r) → !(Rec el rs) → Rec el (r ’: rs)
  • 57. Effects inside records data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where RNil :: Rec el f ’[] (:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs)
  • 58. Effects inside records data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where RNil :: Rec el f ’[] (:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs)
  • 59. Effects inside records data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where RNil :: Rec el f ’[] (:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs) (=:) : Applicative f ⇒ sing r → el $ r → Rec el f ’[r] k =: x = pure x :& RNil
  • 60. Effects inside records data Rec :: (TyFun k ∗ → ∗) → (∗ → ∗) → [k] → ∗ where RNil :: Rec el f ’[] (:&) :: !(f (el $ r)) → !(Rec el f rs) → Rec el f (r ’: rs) (=:) : Applicative f ⇒ sing r → el $ r → Rec el f ’[r] k =: x = pure x :& RNil (⇐): sing r → f (el $ r) → Rec el f ’[r] k ⇐ x = x :& RNil
  • 61. Compositional validation type Validator a = a → Either Error a
  • 62. Compositional validation newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x } type Validator = Lift (→) Identity (Either Error)
  • 63. Compositional validation newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x } type Validator = Lift (→) Identity (Either Error)
  • 64. Compositional validation newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x } type Validator = Lift (→) Identity (Either Error) validateName :: AddrRec Validator ’[Name] validatePhone :: ∀l. AddrRec Validator ’[Phone l] validateEmail :: ∀l. AddrRec Validator ’[Email l]
  • 65. Compositional validation newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x } type Validator = Lift (→) Identity (Either Error) validateName :: AddrRec Validator ’[Name] validatePhone :: ∀l. AddrRec Validator ’[Phone l] validateEmail :: ∀l. AddrRec Validator ’[Email l] type TotalContact = [ Name, Email Home, Email Work , Phone Home, Phone Work ]
  • 66. Compositional validation newtype Lift o f g x = Lift { runLift :: f x ‘o‘ g x } type Validator = Lift (→) Identity (Either Error) validateName :: AddrRec Validator ’[Name] validatePhone :: ∀l. AddrRec Validator ’[Phone l] validateEmail :: ∀l. AddrRec Validator ’[Email l] type TotalContact = [ Name, Email Home, Email Work , Phone Home, Phone Work ] validateContact :: AddrRec Validator TotalContact validateContact = validateName ⊕ validateEmail ⊕ validateEmail ⊕ validatePhone ⊕ validatePhone
  • 68. Record effect operators ( ) :: Rec el (Lift (→) f g) rs → Rec el f rs → Rec el g rs
  • 69. Record effect operators ( ) :: Rec el (Lift (→) f g) rs → Rec el f rs → Rec el g rs rtraverse :: Applicative h ⇒ (∀ x. f x → h (g x)) → Rec el f rs → h (Rec el g rs)
  • 70. Record effect operators ( ) :: Rec el (Lift (→) f g) rs → Rec el f rs → Rec el g rs rtraverse :: Applicative h ⇒ (∀ x. f x → h (g x)) → Rec el f rs → h (Rec el g rs) rdist :: Applicative f ⇒ Rec el f rs → f (Rec el Identity rs) rdist = rtraverse (fmap Identity)
  • 71. Compositional validation bob :: AddrRec [Name, Email Work] validateContact :: AddrRec Validator TotalContact
  • 72. Compositional validation bob :: AddrRec [Name, Email Work] validateContact :: AddrRec Validator TotalContact bobValid :: AddrRec (Either Error) [Name, Email Work] bobValid = cast validateContact bob
  • 73. Compositional validation bob :: AddrRec [Name, Email Work] validateContact :: AddrRec Validator TotalContact bobValid :: AddrRec (Either Error) [Name, Email Work] bobValid = cast validateContact bob validBob :: Either Error (AddrRec Identity [Name, Email Work]) validBob = rdist bobValid
  • 74. Laziness as an effect
  • 75. Laziness as an effect newtype Identity a = Identity { runIdentity :: a } data Thunk a = Thunk { unThunk :: a }
  • 76. Laziness as an effect newtype Identity a = Identity { runIdentity :: a } data Thunk a = Thunk { unThunk :: a } type PlainRec el rs = Rec el Identity rs
  • 77. Laziness as an effect newtype Identity a = Identity { runIdentity :: a } data Thunk a = Thunk { unThunk :: a } type PlainRec el rs = Rec el Identity rs type LazyRec el rs = Rec el Thunk rs
  • 79. Concurrent records with Async fetchName :: AddrRec IO ’[Name] fetchName = SName ⇐ runDB nameQuery
  • 80. Concurrent records with Async fetchName :: AddrRec IO ’[Name] fetchName = SName ⇐ runDB nameQuery fetchWorkEmail :: AddrRec IO ’[Email Work] fetchWorkEmail = SEmail SWork ⇐ runDB emailQuery
  • 81. Concurrent records with Async fetchName :: AddrRec IO ’[Name] fetchName = SName ⇐ runDB nameQuery fetchWorkEmail :: AddrRec IO ’[Email Work] fetchWorkEmail = SEmail SWork ⇐ runDB emailQuery fetchBob :: AddrRec IO [Name, Email Work] fetchBob = fetchName ⊕ fetchWorkEmail
  • 83. Concurrent records with Async newtype Concurrently a = Concurrently { runConcurrently :: IO a }
  • 84. Concurrent records with Async newtype Concurrently a = Concurrently { runConcurrently :: IO a } ( $ ) :: (∀ a. f a → g a) → Rec el f rs → Rec el g rs
  • 85. Concurrent records with Async newtype Concurrently a = Concurrently { runConcurrently :: IO a } ( $ ) :: (∀ a. f a → g a) → Rec el f rs → Rec el g rs bobConcurrently :: Rec el Concurrently [Name, Email Work] bobConcurrently = Concurrently $ fetchBob
  • 86. Concurrent records with Async newtype Concurrently a = Concurrently { runConcurrently :: IO a } ( $ ) :: (∀ a. f a → g a) → Rec el f rs → Rec el g rs bobConcurrently :: Rec el Concurrently [Name, Email Work] bobConcurrently = Concurrently $ fetchBob concurrentBob :: IO (PlainRec el [Name, Email Work]) concurrentBob = runConcurrently (rdist bobConcurrently)
  • 88. Universes `a la Tarski
  • 89. Universes `a la Tarski A type U of codes for types.
  • 90. Universes `a la Tarski A type U of codes for types. Function ElU : U → Type.
  • 91. Universes `a la Tarski A type U of codes for types. Function ElU : U → Type. Γ s : U Γ ElU (s) : Type
  • 92. Universes `a la Tarski Type
  • 93. Universes `a la Tarski  Type
  • 94. Universes `a la Tarski  Type
  • 95. Universes `a la Tarski  Type
  • 97. Records as products Records: the product of the image of ElU in Type restricted to a subset of U.
  • 101. Vinyl: beyond records? Records and corecords are finite products and sums respectively.
  • 102. Vinyl: beyond records? Records and corecords are finite products and sums respectively. Rec(ElU ; F; rs) :≡ U|rs F ◦ ElU
  • 103. Vinyl: beyond records? Records and corecords are finite products and sums respectively. Rec(ElU ; F; rs) :≡ U|rs F ◦ ElU CoRec(ElU ; F; rs) :≡ U|rs F ◦ ElU
  • 104. Vinyl: beyond records? Records and corecords are finite products and sums respectively. Rec(ElU ; F; rs) :≡ U|rs F ◦ ElU CoRec(ElU ; F; rs) :≡ U|rs F ◦ ElU Data(ElU ; F; rs) :≡ WU|rs F ◦ ElU
  • 105. Vinyl: beyond records? Records and corecords are finite products and sums respectively. Rec(ElU ; F; rs) :≡ U|rs F ◦ ElU CoRec(ElU ; F; rs) :≡ U|rs F ◦ ElU Data(ElU ; F; rs) :≡ WU|rs F ◦ ElU Codata(ElU ; F; rs) :≡ MU|rs F ◦ ElU
  • 107. Vinyl: beyond records? (U|rs) (F ◦ ElU ) Π
  • 108. Vinyl: beyond records? (U|rs) (F ◦ ElU ) W
  • 109. Vinyl: beyond records? (U|rs) (F ◦ ElU ) M
  • 111. 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.
  • 112. Topologies on some space X
  • 113. Topologies on some space X What are the open sets on X?
  • 114. Topologies on some space X What are the open sets on X? The empty set and X are open sets
  • 115. 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
  • 116. 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
  • 118. Records are presheaves Let O = P, the discrete topology
  • 119. 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
  • 120. 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 U ∈ P(X) R(U) :≡ U ElX|U : Type
  • 121. 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 U ∈ P(X) R(U) :≡ U ElX|U : Type for i : V → U R(i) :≡ cast : R(U) → R(V )
  • 123. 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))
  • 124. 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))
  • 126. Records with non-trivial topology NameType :≡ {F, M, L}
  • 127. Records with non-trivial topology NameType :≡ {F, M, L} A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label}
  • 128. Records with non-trivial topology NameType :≡ {F, M, L} A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label} ElA :≡ λ .String
  • 129. Records with non-trivial topology NameType :≡ {F, M, L} A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label} ElA :≡ λ .String T :≡ {U ∈ P(A) | Name[M] ∈ U ⇒ {Name[F], Name[L]} ⊆ U}
  • 130. Records with non-trivial topology NameType :≡ {F, M, L} A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label} ElA :≡ λ .String T :≡ {U ∈ P(A) | Name[M] ∈ U ⇒ {Name[F], Name[L]} ⊆ U} ex : RT ({Name[t] | t ∈ NameType}) ex :≡ {Name[F] → ”Robert”; Name[M] → ”W”; Name[L] → ”Harper”}
  • 131. Records with non-trivial topology NameType :≡ {F, M, L} A :≡ {Name[t] | t ∈ NameType} ∪ {Phone[ ] | ∈ Label} ElA :≡ λ .String T :≡ {U ∈ P(A) | Name[M] ∈ U ⇒ {Name[F], Name[L]} ⊆ U} ex : RT ({Name[t] | t ∈ NameType}) ex :≡ {Name[F] → ”Robert”; Name[M] → ”W”; Name[L] → ”Harper”} nope : RT ({Name[M], Phone[Work]}) nope :≡ {Name[M] → ”W”; Phone[Work] → ”5555555555”}
  • 133. Future work Complete: formalization of records with topologies as presheaves in Coq
  • 134. Future work Complete: formalization of records with topologies as presheaves in Coq In Progress: formalization of records as sheaves
  • 135. Future work Complete: formalization of records with topologies as presheaves in Coq In Progress: formalization of records as sheaves Future: extension to dependent records using extensional type theory and realizability (Nuprl, MetaPRL)