Прочитайте и поймите распылительную DSL

Я новичок в спрей. У меня есть работа с несколькими странными (для меня) языками программирования, такими как python, JQuery и т. Д. С ними я, по крайней мере, мог понять, что делает какой-то сегмент кода. К сожалению, с помощью Spray я не могу прочитать и понять даже простой код.

Может кто-нибудь, пожалуйста, помогите мне прочитать (опишите словом, что делает код) следующий простой блок кода.

Примечание: я знаю, что это очень высокий уровень, он выберет параметр url и сложит их вместе. Но я хочу четко понимать этот кристалл кодового блока, как я мог бы научить кого-то другого. HNil, Directive1, Directive1, :: некоторые, что странно для меня.

val twoIntParameters: Directive[Int :: Int :: HNil] =
  parameters('a.as[Int], 'b.as[Int])

val myDirective: Directive1[String] =
  twoIntParameters.hmap {
    case a :: b :: HNil => (a + b).toString
  }

// test `myDirective` using the testkit DSL
Get("/?a=2&b=5") ~> myDirective(x => complete(x)) ~> check {
  responseAs[String] === "7"
}

2 ответа

Решение

Распылитель строится вокруг концепции Directive,

Вы можете думать о Directive как преобразование по HTTP-запросу.

Количество элементов, связанных с директивой - это число аргументов, передаваемых по цепочке преобразования после выполнения преобразования.

Directive0 директива, которая не предоставляет (или не извлекает) никаких аргументов.

Directive1[A] предоставляет один аргумент типа A,

Directive[A :: B :: HNil] предоставляет 2 аргумента типов A а также B или - если быть более точным - предоставляет гетерогенный список, состоящий из A а также B (реализация бесформенная HList).

Давайте возьмем примеры в вашем коде

val twoIntParameters: Directive[Int :: Int :: HNil] =
  parameters('a.as[Int], 'b.as[Int])

Вы определяете новую директиву, которая извлекает два целых числа из запроса HTTP, т.е. имеет тип Directive[Int :: Int :: HNil], Реализация просто использует директиву, предоставленную уже спреем, т.е. parameters, parameters директива, которая позволяет извлечь параметры запроса из HTTP-запроса и преобразовать их в определенный тип, в данном случае Int для обоих параметров.

val myDirective: Directive1[String] =
  twoIntParameters.hmap {
    case a :: b :: HNil => (a + b).toString
  }

myDirective директива, которая извлекает один параметр типа String,

В его реализации используются ранее определенные twoIntParameters директива и отображает ее результат, применяя к ней преобразование. В этом случае мы берем два Int суммируя их и превращая результат в String,

Итак, что с hmap? Это просто способ работы с директивами, которые возвращают бесформенный HList, hmap требует функции, которая HList ни к чему, в этом случае String,

HList s может быть сопоставлен с шаблоном, как обычная скала List и вот что вы видите в примере.

Наконец, это просто представление о том, как директивы работают с функциональной точки зрения. Если вы хотите понять тонкие детали синтаксиса DSL, вам придется немного покопаться и прочитать о шаблоне магнитов.

Здесь я нашел очень хорошую мастерскую.

https://www.youtube.com/watch?v=XPuOlpWEvmw

Другие вопросы по тегам