Scala, коты - как не использовать Applicative[F] явно?

Я хотел бы использовать Applicative[F] как-то иначе, чем явно. В настоящее время у меня есть простой код:

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 для возврата F[Bet]. Есть ли способ сделать это не так (чтобы не вызывать метод pure явно)? Я пытался сделать что-то вроде этого:

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, поэтому я и спрашиваю об этом. Я не думаю, что явный вызов методов, таких как pure, является хорошей практикой. Не могли бы вы помочь мне с этим?


person Developus    schedule 20.04.2019    source источник


Ответы (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.

person Some Name    schedule 20.04.2019