Scala, котки - как да не използвам Applicative[F] explicity?

Бих искал да използвам 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 на simulacrum.

person Some Name    schedule 20.04.2019