首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kleisli flatMap stange型参数子类型

Kleisli flatMap stange型参数子类型
EN

Stack Overflow用户
提问于 2021-03-20 18:04:06
回答 1查看 60关注 0票数 0

有人能向我解释一下为什么flatMap在猫身上的签名如下:

代码语言:javascript
复制
def flatMap[C, AA <: A](f: B => Kleisli[F, AA, C])(implicit F: FlatMap[F]): Kleisli[F, AA, C] =
    Kleisli.shift(a => F.flatMap[B, C](run(a))((b: B) => f(b).run(a)))

我真正不明白的是,AA <: A为什么AA必须是A的subType?

我得到了克莱斯里的平面图操作,这是我没有得到的subTyping吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-24 08:46:03

因为你可以,这有时会让生活更轻松。

假设我们有一些子类型

代码语言:javascript
复制
trait Animal {
  def makeNoise: IO[Unit]
}

case class DogFood(label: String)

case class Dog(name: String) extends Animal {
  def makeNoise = IO.println(s"$name says Woof!")
  def consumeEdibles(df: DogFood) = IO.println(s"$name ate '${df.label}'. Yum!")
}

我们能制造出很少的Kleislis:

代码语言:javascript
复制
val doNoise = Kleisli((_: Animal).makeNoise)
val eatNewFood = Kleisli((_: Dog).consumeEdibles(new DogFood("Fancy Dog Food")))

注意,它们中的第一个只需要一个Animal,但是可以用一个Dog调用它们。这听起来是合理的,我们可以以某种方式将两者组合成一个单独的Kleisli,可以用一只狗来命名。对吗?让我们试一试。

如果你从一只狗开始工作,克莱斯里:

代码语言:javascript
复制
// Both valid - contravariance makes it so that doNoise : Kleisli[IO, Animal, Unit]
// extends Kleisli[IO, Dog, Unit] and compiler figures it out. Result is Kleisli[IO, Dog, Unit]
eatNewFood.flatMap(_ => doNoise)
(eatNewFood >> doNoise)

但请注意,您是如何不能这样做的:

代码语言:javascript
复制
(doNoise >> eatNewFood)

那是因为>>是“愚蠢的”。因为您从Kleisli[IO, Animal, Unit]开始,所以需要下一个也是Kleisli[IO, Animal, something]

不过,我们可以通过让编译器在推断>>的类型之前扩展Kleisli来纠正它。

((doNoise: Kleisli[IO, Dog, Unit]) >> eatNewFood)

这是冗长而丑陋的。如果我们能告诉你“嘿,而不是要求右手边是一个更宽的类型,允许结果是一个更窄的类型,对两者都是有效的”,那就太好了。

flatMap的签名就是这么说的。亚型意味着较窄的AA型可以代替更宽的A型,用于左手侧和右手侧。

代码语言:javascript
复制
// Valid because of this trick you're asking about
// Here AA = Dog <: Animal = A
// Result value is Kleisli[F, AA, C] which resolves to Kleisli[IO, Dog, Unit]
doNoise.flatMap(_ => eatNewFood)

我们失去的只是一些缩小输入的类型,没有人喜欢这些。

请注意,AA和A一样满足AA <:A。因此,虽然它不必是不同的子类型,但它可以而且是合法的,而且是合理的(可以使用Dog =>调用两者,可以将它们组合成可以用Dog调用的东西)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66724859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档