The Dialectics of Type-Level Programming; or How I Learned To Love Values
¡Hola!
thank you
Soy Aaron Levin
Recommendations @
MSc. Mathematics
@aaronmblevin
today
we are going to do great things
DSL
Domain
Specific
Language
GNU make
Verilog
eDSL
embedded
Domain
Specific
Language
val a = actor(new Act {
become {
case "Lambda" ⇒ sender() ! "World"
}})
"Lambda World" must haveSize(11)�"Lambda World" must startWith("Lambda")�"Lambda World" must endWith("World")
main = do� r <- runHaxl env $ do� likes <- getObject "lambda/world"� mapM getObject (likeIds likes)
eDSL
Value
Domain-Specific
Meaning
combinators
" " must have("sword")�" " must startWith("flames")�" " must endWith("flames")�
combinators
eDSLs are not extensible
:( :( :(
Type-Level DSL
Type-Level DSL
Value
Domain-Specific
Meaning
combinators
Type
Value
Type Class resolution
Type-Level DSLs are
extensible
example
Servant
(haskell)
Example: Servant
type HackageAPI =� -- GET /user� "user" :> Get '[JSON] [UserSummary]� -- GET /user/:username� :<|> "user" :> Capture "username" Username :> Get '[JSON] UserDetailed� :<|> "packages" :> Get '[JSON] [Package]
Type Class resolution
(value)
Haskell Client
(value)
Web Server
(value)
Mock Server
let’s build a Type-Level DSL
together
The Problem: Heterogeneous Event Sink
Event sink
“data lake”
event: play
event: pause
event: click
The Problem: Heterogeneous Event Sink
Event sink
event: play
event: pause
event: click
{ “name”: “click”,� “payload”: { ... }�}
{ “name”: “play”,� “payload”: { ... }�}
{ “name”: “pause”,� “payload”: { ... }�}
{ “name”: “click”,
“payload”: {
“user”: “lambda”,� “page:” “track/world”
}
}
{ “name”: “play”,
“payload”: {
“user”: “lambda”,� “track:” 420
}
}
The Problem: Heterogeneous Event Sink
Our Event Sink must:
Our Type-Level DSL: Three Steps
Haskell
type Events = � ( Click, � ( Play, � ( Pause,� EndOfList) ) )
Scala
type Events = � ( Click,� ( Play, � ( Pause,� EndOfList) ) )
Encoding Lists of Types as Embedded Tuples
type EndOfList = Unit
[Int, String, Char] → (Int, (String, (Char, EndOfList))))
let’s begin!
source: http://jjjjjjjjjjohn.tumblr.com/
A little bit about typeclass induction
induction: base case
implicit val baseCaseName = new Named[EndOfList] { � val name = “”�}
induction step
type Events = (Click, (Play, (Pause, EndOfList)))�type Events = (� (Click, Named[(Click, (Play, (Pause, EndOfList)))]�
(Play, Named[(Play,(Pause, EndOfList))]�
(Pause, Named[(Pause, EndOfList)]�
EndOfList))) Named[EndOfList]
implicit val
implicit def
implicit def
implicit def
dynamic dispatch,
statically!
Recap: interpreter #1
type Events = (Click, (Play, (Pause, EndOfList)))��trait Named[E] { val name: String }�implicit val namedClick: Named[Click]�implicit val namedPlay: Named[Play]�implicit val namedPause: Named[Pause]�implicit val namedBaseCase: Named[EndOfList]�implicit def induction[E](implicit t: Named[Tail]): Named[(E,Tail)]
$ getNamed[Events] = “click, play, pause,”
Recap: interpreter #2
type Events = (Click, (Play, (Pause, EndOfList)))��trait HandleEvents[E] {� type Out� def handleEvent(s: String, String): Either[String, Out] �}�implicit def induction[E](implicit n: Named[E], f: FromString[E], t: HandleEvents[Tail]): HandleEvents[(E,Tail)]
$ handleEvent[Events]("play", "lambdaworld\t123") =� “Right(Left(Right(Play(lambdaworld,123))))”
can we have it all?
almost?....!
No instance for (FromString Int) arising from a use of ‘handleEvent’
error: could not find implicit value for parameter names:
HandleEvents[Events]
handleEvent :: Handle events => Proxy events -> String -> String -> Out events
handleEvent :: Handle events => String -> String -> Out events
Couldn't match type ‘Out events’ with ‘Out events0’�NB: ‘Out’ is a type function, and may not be injective�The type variable ‘events0’ is ambiguous�Expected type: String -> String -> Out events� Actual type: String -> String -> Out events0�In the ambiguity check for the type signature for ‘handle’:� handle :: forall (k :: BOX) (events :: k).�…….�…….�…….
Dialectics
Dialectics
DSLs
Type-Level DSLs
contradiction
Extensibility
Dialectics
Runtime
Bugs
Compiler
Bugs
❤️
Interpreting Values
contradiction?
Recap
thank you
(everything after this slide are rejected slides)
❤️ Values
Dialectics
Object
Function
???
contradiction
Dialectics
Thesis
Antithesis
Synthesis
contradiction
Type-Level DSL
Value
Domain-Specific
Meaning
combinators
Type
???
compiler
induction
be like