斯卡拉,猫。有人可以解释什么是 `F` 以及它从何而来?

Scala, Cats. Can someone explain what is `F` and where does it come from?

我想使用该存储库中的 cats-saga:https://github.com/VladKopanev/cats-saga

但是我被困在 OrderSagaCoordinator.scala L160 的那段代码上:

def apply[F[_]: Sync: Concurrent: Timer: Sleep: Parallel](
    paymentServiceClient: PaymentServiceClient[F],
    loyaltyPointsServiceClient: LoyaltyPointsServiceClient[F],
    orderServiceClient: OrderServiceClient[F],
    sagaLogDao: SagaLogDao[F],
    maxRequestTimeout: Int
  ): F[OrderSagaCoordinatorImpl[F]] =

什么是F,它是从哪里来的,谁能解释一下那段代码?

谢谢

编辑: 我知道泛型是什么。但是,在那种情况下,调用 apply 方法时未指定具体类型,我看不到它的来源。

(for {
      paymentService <- PaymentServiceClientStub(randomUtil, clientMaxReqTimeout, flakyClient)
      loyaltyPoints  <- LoyaltyPointsServiceClientStub(randomUtil, clientMaxReqTimeout, flakyClient)
      orderService   <- OrderServiceClientStub(randomUtil, clientMaxReqTimeout, flakyClient)
      xa             = Transactor.fromDriverManager[IO]("org.postgresql.Driver", "jdbc:postgresql:Saga", "postgres", "root")
      logDao         = new SagaLogDaoImpl(xa)
      orderSEC       <- OrderSagaCoordinatorImpl(paymentService, loyaltyPoints, orderService, logDao, sagaMaxReqTimeout)

    // ...

想一些具体的事情,比如'box of chocolates'

case class Box(v: Chocolate)

现在想象一下我们拿走巧克力,让盒子里有任何一种元素A,可能是一盒硬币、一盒糖果、一盒卡片等

case class Box[A](v: A)

这里我们在box的元素类型上进行了多态。许多语言都可以表达这种级别的多态性。但 Scala 更进一步。就像我们拿走巧克力一样,我们可以拿走盒子本身,本质上表达了一个非常抽象的想法“任何类型元素的任何类型的上下文”[=32] =]

trait Ctx[F[_]]

作为另一个类比,考虑以下

box of chocolate  -> proper type                      -> case class Box(v: Chocolate)
box of _          -> type constructor of first order  -> case class Box[A](v: A)
_   of _          -> type constructor of higher order -> trait Ctx[F[_]]

现在关注_ of _。在这里我们有“某物的某物”,这似乎我们什么都没有。我们怎么能用这个做任何事情?这就是 类型 class 的想法发挥作用的地方。类型 class 可以约束高度多态的形状,例如 F[_]

def apply[F[_]: Sync](...)

这里[F[_]: Sync]表示这个约束。这意味着方法 apply 接受任何第一类构造函数,有证据表明它满足类型 class Sync 的约束。请注意,类型 class Sync

trait Sync[F[_]]

被认为是高阶类型构造函数,而类型参数 F[_] 表示一阶类型构造函数。同样

F[_] : Sync : Concurrent

指定类型构造函数F不仅要满足Sync约束,还要满足Concurrent类型class的约束,依此类推。这些技术有时被称为可怕的声音

higher order type constructor polymorphism

但我相信大多数程序员都已经具备理解它的所有概念工具,因为

  1. 如果您曾经将一个函数传递给另一个函数,那么您可以使用 高阶
  2. 的概念
  3. 如果您曾经使用过 List,那么您可以使用 类型构造函数
  4. 的概念
  5. 如果您曾经编写过对整数和双精度使用相同实现的方法,那么您可以使用 多态性
  6. 的概念

提供 证据 类型构造函数满足类型 class 的约束是使用 Scala 的 implicit 机制给出的。 IMO Scala 3 大大简化了这个概念,所以考虑 https://dotty.epfl.ch/docs/reference/contextual/type-classes.html