Scala, Cats, использование `ap`

Я прохожу через https://www.scala-exercises.org/ для кошек. Думаю, я понимаю, что значит Apply.ap. Но я не вижу в этом никакого применения.

В чем разница между:

Apply[Option].map(Some(1))(intToString)

и

Apply[Option].ap(Some(intToString))(Some(1))

Может кто-нибудь объяснить немного больше или указать мне больше объяснений?


person gervais.b    schedule 13.11.2020    source источник
comment
Честно говоря, я никогда не использовал ap напрямую. Скорее, я использовал его неявно, используя такие вещи, как tupled, mapN и traverse.   -  person Luis Miguel Mejía Suárez    schedule 13.11.2020
comment
Спасибо, это было мое понимание не в пользовательском коде. Луис, есть еще apN как mapN, но я думаю, что ответ тот же.   -  person gervais.b    schedule 13.11.2020
comment
Apply - это специализированный класс типа Applicative, который также является функтором. Applicative обеспечивает ap работу. Она очень похожа на карту Functor, но функция в аргументе уже находится в F[_] домене. Во многих случаях, таких как моноиды, они могут использоваться взаимозаменяемо, за некоторыми исключениями.   -  person texasbruce    schedule 13.11.2020
comment
В FP ap чаще используется композиция с map формы ap(map), более известная как liftA2. Обратите внимание, что ap - очень фундаментальная операция, и вы должны знать, когда использовать ее вместо flatMap.   -  person Iven Marquardt    schedule 13.11.2020


Ответы (1)


Нет разницы между

Apply[Option].map(Some(1))(intToString)

и

Apply[Option].ap(Some(intToString))(Some(1))

Оба Some("1").

Но есть большая разница между map и ap.

map происходит от класса типа Functor и имеет подпись

def map[A, B](fa: F[A])(f: A => B): F[B]

ap происходит от класса типа Apply и имеет подпись

def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]

Таким образом, map применяет функцию A => B к значению в контексте F[A], а ap применяет функцию F[A => B] в контексте к значению в контексте F[A] .

Например

Apply[List].map(List(1, 2))(intToString)

List("1", "2") в то время как

Apply[List].ap(List(intToString, (i: Int) => intToString(i) + "a"))(List(1, 2))

is List("1", "2", "1a", "2a").

Apply[Option].map(fx)(f) может быть None, только когда fx равно None, а Apply[Option].ap(ff)(fx) может быть None, когда fx равно None или ff равно None.

person Dmytro Mitin    schedule 13.11.2020