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")