在Scala中管理内容通常非常简单 - 对于集合,map
和compose
function composition,请考虑andThen
。
但是,我似乎找不到将两者结合起来的方法。我有一个返回Option[Double]
的函数。我希望过滤Double
值(降低其精度),如果它在那里。 andThen
已接近但需要我处理选项。
在Scala 2.11中有没有一个很好的内置方法来处理它?</ p>
class Temp( ff: (Object) => Option[Double] )
object Temp {
def apply( f: (Object) => Option[Double] ) = {
def cutTo5Digits(v: Double): Double = {
v - (v % 1e-5)
}
// call 'f', then pipe its output (if some) via 'cutTo5Digits'?
//
//new Temp( f map cutTo5Digits ) // nope
//new Temp( f _ andThen cutTo5Digits _ ) // would need option unwrapping
new Temp((o: Object) => f(o) map ((v: Double) => cutTo5Digits(v))) // compiles
}
}
答案 0 :(得分:2)
我认为最好的解决方案是new Temp(f(_) map cutTo5Digits)
,它有什么问题?
但是如果你想要这样的语法:f map cutTo5Digits
,那么你可以使用scalaz中的Kleisli,其中f
的类型为Kleisli[Option, Object, Double]
,即:
def apply( f: (Object) => Option[Double] ) = {
def cutTo5Digits(v: Double): Double = v - (v % 1e-5)
val ff = Kleisli(f)
new Temp(ff map cutTo5Digits) // or inline Kleisli(f) map ...
}
或者您也可以cutTo5Digits
类型为Double => Option[Double]
,此类函数可以使用Kliesli >=>
方法进行链接,您可以将其重写为ff >=> cutTo5Digits
。
答案 1 :(得分:2)
如果您想使用andThen
语法,可以将函数升级为仿函数,例如:
def liftOption[A, B](f: A => B): Option[A] => Option[B] = _.map(f(_))
要突出显示功能组成,您现在可以写:
(f _) andThen liftOption(cutTo5Digits _)
如果您隐式进行此转换,您甚至可以使用原始f _ andThen cutTo5Digits _
。如果您使用的是Scalaz,则应该可以通过cutTo5Digits.lift[Option]
解除功能。