只要我们有一个PartialFunction[X,R]
很容易将它转换为返回的函数Option[R]
,例如
def pfToOptf[X, R](f: PartialFunction[X,R])(x: X) = if (f.isDefinedAt(x)) Some(f(x)) else None
但是,如果任务相反,那该怎么办:假设我有一个函数作为参数f
获取X
并返回Option[R]
结果.我想做出一个PartialFunction[X,R]
.什么是最好的方法?
我想出来的东西看起来很丑陋我的口味:
def optfToPf[X,R](f: X => Option[R]) : PartialFunction[X,R] = { object extractor { def unapply(x: X): Option[R] = f(x) } { case extractor(r) => r } }
我错过了一些更好的方法吗?
我知道这是一个旧线程,但如果有其他人遇到这个,Function.unlift正是这样做的.
这个怎么样:
Welcome to Scala version 2.8.0.r19650-b20091114020153 (Java HotSpot(TM) Client VM, Java 1.6.0_17). Type in expressions to have them evaluated. Type :help for more information. scala> def optfToPf[X,R](f: X => Option[R]): PartialFunction[X,R] = x => f(x) match { | case Some(r) => r | } optfToPf: [X,R](f: (X) => Option[R])PartialFunction[X,R] scala>
我想你可以手动覆盖apply和isDefinedAt,但我会按照你发现丑陋的方式来做.
def optfToPf[X,R](f: X => Option[R]) = new PartialFunction[X,R] { def apply(x: X): R = f(x).get def isDefinedAt(x: X): Boolean = f(x) != None }
测试:
scala> val map = Map(1 -> 2) map: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2) scala> map(1) res0: Int = 2 scala> def mapOpt(key: Int) = map.get(key) mapOpt: (key: Int)Option[Int] scala> mapOpt(1) res1: Option[Int] = Some(2) scala> mapOpt(2) res2: Option[Int] = None scala> val mapPf = optfToPf(mapOpt _) mapPf: java.lang.Object with PartialFunction[Int,Int] =scala> mapPf.isDefinedAt(2) res3: Boolean = false scala> mapPf.isDefinedAt(1) res4: Boolean = true scala> mapPf(1) res5: Int = 2 scala> mapPf(2) java.util.NoSuchElementException: None.get