使用Scalaz,函数可以映射到另一个函数.什么时候我会想使用map过andThen?使用有明显的优势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
Run Code Online (Sandbox Code Playgroud)
Tra*_*own 12
暂时搁置实现细节,map 是 andThen针对函数(在函数实例下A => ?),如果我们专门讨论函数而不是更高级函数,那么谈论优先于其他函数并不是很有意义.抽象程度.
像map(和Functor更普遍的类型类)允许我们做的是什么方法是抽象的特定类型或类型构造函数.假设我们要编写一个incrementResult使用这两种方法工作A => Int或者Kleisli[Option, A, Int],例如.这些类型没有在继承方面的任何共同点(短的AnyRef,这是无用的),但A => ?和Kleisli[Option, A, ?]都是仿函数,所以我们可以这样写:
import scalaz._, Scalaz._
def incrementResult[F[_]: Functor](f: F[Int]): F[Int] = f.map(_ + 1)
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它(注意我使用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)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,特别是有更好的方法来实现这个操作,但它显示了一般的想法 - 我们不能编写一个适用于普通函数和Kleisli箭头使用的方法andThen,但我们可以使用额外的抽象级别map给出我们.
因此,要回答你的问题-你会用map,如果你想在抽象有一个仿函数实例的所有类型构造,但如果你有专门职能部门紧密合作,map 是 andThen和-只要我们还在留出实施细则 - 你选择哪个并不重要.
脚注:mapScalaz的syntax包为您提供了具有functor实例的类型的值作为扩展方法实现,因此在使用map而不是andThen在函数上涉及一小部分开销(在编译时和运行时).如果你只是在处理函数而不需要额外的抽象,那么你也可以选择andThen.
| 归档时间: |
|
| 查看次数: |
456 次 |
| 最近记录: |