gpt4 book ai didi

scala - 当你有 andThen 时映射函数很有用

转载 作者:行者123 更新时间:2023-12-04 06:16:20 24 4
gpt4 key购买 nike

使用 Scalaz,一个函数可以映射到另一个函数上。我什么时候想使用 mapandThen ?使用 map 是否有明显优势? ?谢谢

例如,

val f: Int => Int = (a) => a + 10

val g: Int => Int = (a) => a * 100

(f map g map {_*3})(10) == (f andThen g andThen {_*3})(10) // true

最佳答案

暂时搁置实现细节,mapandThen对于函数(在 A => ? 的仿函数实例下),如果我们专门讨论函数而不是更高级别的抽象,那么谈论更喜欢一个而不是另一个并没有多大意义。

有什么方法像map (以及更普遍的类型类,如 Functor)允许我们对特定类型或类型构造函数进行抽象。假设我们要写一个 incrementResult适用于两者的方法 A => IntKleisli[Option, A, Int] , 例如。这些类型在继承方面没有任何共同点(缺少 AnyRef ,这是无用的),但是 A => ?Kleisli[Option, A, ?]都是仿函数,所以我们可以这样写:

import scalaz._, Scalaz._

def incrementResult[F[_]: Functor](f: F[Int]): F[Int] = f.map(_ + 1)

然后像这样使用它(请注意,我正在使用 kind-projector 来稍微简化类型语法):
scala> val plainOldFuncTriple: Int => Int = _ * 3
plainOldFuncTriple: Int => Int = <function1>

scala> val optionKleisliTriple: Kleisli[Option, Int, Int] = Kleisli(i => Some(i * 3))
optionKleisliTriple: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)

scala> val f = incrementResult[Int => ?](plainOldFuncTriple)
f: Int => Int = <function1>

scala> val k = incrementResult[Kleisli[Option, Int, ?]](optionKleisliTriple)
k: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)

scala> f(10)
res0: Int = 31

scala> k(10)
res1: Option[Int] = Some(31)

在这种情况下,特别是有更好的方法来实现这个操作,但它显示了一般的想法——我们无法使用 andThen 编写一个既适用于普通函数又适用于 Kleisli 箭头的方法。 ,但我们可以使用额外的抽象级别 map给我们。

所以要回答你的问题——你会使用 map如果你想抽象所有具有仿函数实例的类型构造函数,但如果你专门处理函数, mapandThen ,而且——只要我们还在搁置实现细节——你选择哪个并不重要。

脚注: map Scalaz 的 syntax包为您提供具有仿函数实例的类型的值作为扩展方法实现,因此使用 map 涉及一点点开销(在编译时和运行时)。而不是 andThen在一个函数上。如果您只使用函数而不需要额外的抽象,那么您不妨使用 andThen .

关于scala - 当你有 andThen 时映射函数很有用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38158714/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com