Applicative style using cats library

Это продолжение моего предыдущего вопроса:

Предположим, я хочу использовать Applicative to apply function A => B => C в List[A] а также List[B],
I believe it looks like that in Haskell:

pure f <*> as <*> bs // apply f to List[A] and List[B]

или же

f <$> as <*> bs 

Есть ли cats provide such a syntax? How would you write it with cats?

1 ответ

Решение

Сначала несколько определений

import cats._, implicits._
val as = List(1, 2)
val bs = List("a", "b")

Карри Функитон

Если у вас есть функция карри, например,

val f = (i: Int) => (s: String) => Vector.fill(i)(s).mkString("")

затем pure f <*> as <*> bs Выражение прямо переводится на кошек как

f.pure[List].ap(as).ap(bs)

А также f <$> as <*> bs становится

as.map(f).ap(bs)

Да, порядок уже не такой естественный.


Некурри функция

В Scala очень часто вы будете иметь дело с функциями, принимающими несколько параметров:

val f2 = (i: Int, s: String) => Vector.fill(i)(s).mkString("")
// or val f2 = Function.uncurried(f)

Для этих, cats обеспечивает CartesianBuilder синтаксис:

(as |@| bs).map(f2)

Или, в более новых версиях, синтаксис кортежа с map# метод (который подлежит переименованию, IIRC)

(as, bs).map2(f2)

Все эти фрагменты оценивают как List("a", "b", "aa", "bb")

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