斯卡拉,猫。有人可以解释什么是 `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
但我相信大多数程序员都已经具备理解它的所有概念工具,因为
- 如果您曾经将一个函数传递给另一个函数,那么您可以使用 高阶
的概念
- 如果您曾经使用过
List
,那么您可以使用 类型构造函数 的概念
- 如果您曾经编写过对整数和双精度使用相同实现的方法,那么您可以使用 多态性
的概念
提供 证据 类型构造函数满足类型 class 的约束是使用 Scala 的 implicit
机制给出的。 IMO Scala 3 大大简化了这个概念,所以考虑 https://dotty.epfl.ch/docs/reference/contextual/type-classes.html
我想使用该存储库中的 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
但我相信大多数程序员都已经具备理解它的所有概念工具,因为
- 如果您曾经将一个函数传递给另一个函数,那么您可以使用 高阶 的概念
- 如果您曾经使用过
List
,那么您可以使用 类型构造函数 的概念
- 如果您曾经编写过对整数和双精度使用相同实现的方法,那么您可以使用 多态性 的概念
提供 证据 类型构造函数满足类型 class 的约束是使用 Scala 的 implicit
机制给出的。 IMO Scala 3 大大简化了这个概念,所以考虑 https://dotty.epfl.ch/docs/reference/contextual/type-classes.html