Scala, cats — как не использовать Applicative [F] explicity?

#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 .