#scala #scala-cats #applicative
#scala #scala-кошки #аппликативный
Вопрос:
Я хотел бы использовать Applicative[F]
каким-то другим способом, чем explicity. В настоящее время у меня есть простой код:
class BettingServiceMock[F[_] : Async] extends BettingService[F] {
override def put(bet: Bet): F[Bet] = {
for {
created <- Bet(Some(BetId(randomUUID().toString)), bet.stake, bet.name).pure
} yield created
}
}
Bet
это просто case class
. Я использую метод pure
explicity для возврата F[Bet]
. Есть ли какой-нибудь способ сделать это не так (не вызывать pure
метод explicity)?
Я пытался сделать что-то вроде этого:
class BettingServiceMock[F[_] : Async] (implicit a:Applicative[F]) extends BettingService[F] {
override def put(bet: Bet): F[Bet] = {
for {
created <- Bet(Some(BetId(randomUUID().toString)), bet.stake, bet.name)
} yield created
}
}
Это не помогло, потому что я получил сообщение об ошибке:
value map is not a member of model.Bet <- (Some(BetId(randomUUID().toString)), bet.stake, bet.name)
Я хотел бы найти хорошую практику в Cats
том, как я спрашиваю об этом. Я не думаю, что эксплицитный вызов methids like pure
является хорошей практикой. Не могли бы вы помочь мне с этим?
Ответ №1:
Прежде всего, почему вы думаете, что это плохая практика. Это обычный Applicative
синтаксис. Если вы хотите, чтобы какая-то «магия» автоматически повышала ваше значение Bet
Applicative[Bet]
, тогда вам потребуется какое-то неявное преобразование, и это было бы действительно плохой практикой.
Вы посмотрите на пример scaladoc Applicative
https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/Applicative.scala
Applicative[Option].pure(10)
Здесь Applicative[Option]
был вызван экземпляр apply[F[_]](implicit instance: Applicative[F])
, который автоматически генерируется симулякром @typeclass
.