Typelevel

DSL

present day

present time

Все знают,

что такое

DSL, 

и зачем 

они нужны

Specific

name = readLine("name")
age = readLine("age")
putLine(name)
putLine(age)

Domain

Language

<Program>
    <setVariable name="name">
        <readLine prompt = "name"/>
    </setVariable>
    <setVariable name="age">
        <readLine prompt= "age"/>
    </setVariable>
    <putLine title = "name">
        <getVariable name= "name"/>
    </putLine>
    <putLine title = "age">
        <getVariable name = "age"/>
    </putLine>
</Program>
- cmd: set
  name: name
  value: 
    cmd: readLine
    promt: name
- cmd: set
  name: age
  value: 
    cmd: readLine
    promt: age
- cmd: putLine
  title: name
  value:
    - cmd: get
      name: name
- cmd: putLine
  title: age
  value:
    - cmd: get
      name: age

Runtime

Errors

def program[F[_] : Console]: F[Unit] = 
    for {
       name <- readLine("name")
       age <- readLine("age")
       _ <- putLine("name")(name)
       _ <- putLine("age")(age)
    } yield ()

Free Algebras

Freer/Eff

Finally tagless

def program[~:>[_[_], _[_, _] : Console, 
           Env[_,_]]]: Initial ~:> Env = 
    ('name := readLine("name")) >->
    ('age := readLine("age")) >->
    do_(putLine("name") $ 'name) >->
    do_(putLine("age") $ 'name) 

much free

so composable

Eff

kiselyov ftp wow

very tagless

import doge.implicits._

compilation time: 13 days

Все знают,

что такое 

Типы,

и зачем 

они нужны

case class User(
    name: String, 
    age: Int
    )

Описывают

низкоуровневую структуру

def combineAll[A: Monoid](
     xs: List[A]
    ): A

Накладывают ограничения

Открывают избирательный

доступ к функционалу

trait PrependOrdered[
    N <: Nat, 
    Len <: Nat, 
    V <: OrderedVec[L]]{
  type Result <: OrderedVec[S[Len]]
  def append(xs: V): Result
}

Могут служить доказательтвами

implicit val intEncoder extends Encoder[Int]

implicit def listEncoder[A]
 (implicit item: Encoder[A]): Encoder[List[A]]
implicitly[Encoder[List[Int]]
listEncoder(intEncoder)
type Program = 
    ('name := readLine["name"]) >>
    ('age  := readLine["age"])  >>
    (putLine["name"] $ 'name)   >>
    (putLine["age"]  $ 'age) 
trait Program

case class ReadLine(name: String) extends Program
case class PutLine(name: String) extends Program
case class Cons(left: Program, right: Program) extends Program
trait Program

trait ReadLine[name <: String] extends Program
trait WriteLine[name <: String] extends Program
trait Cons[left <: Program, right <: Program] extends Program

LAYER1: IMPLICITS

TRUE WAY

Text

SANE WAY

LAYER 2: MACROS

LAYER 3: EFFECTS

NO WAY

THIS ISN'T EVEN

MY FINAL FORM

Что нужно?

implicit def cons[
  left,
  right,
  Input]
  (implicit left: Interpret[left, Input])
  (implicit right: Interpret[right, left.Output])
  : Interpret[left >> right, Input]{type Output = right.Output}

Multiple implicit parameter lists

(https://github.com/lampepfl/dotty/issues/1260)

Typelevel Functions

type def LiftRecord[R <: Record[F], G[_]] = R match {
   case RNil[F] => RNil[G]
   case RCons[F, K, V, Tail] => 
     RCons[G, K, LiftValue[V, G], LiftRecord[G]]
}

Что нужно?

Спасибо за внимание!

typelevel dsl

By Oleg Nizhnik

typelevel dsl

  • 1,252