相关疑难解决方法(0)

PartialFunction设计效率低下吗?

这是我一段时间都想知道的事情.我看到这种模式很多:

if (pf.isDefinedAt(in)) pf(in)
Run Code Online (Sandbox Code Playgroud)

通过将其分解为两个单独的调用,在#isDefinedAt中计算的所有模式也将在#apply中进行评估.例如:

object Ex1 {
  def unapply(in: Int) : Option[String] = {
    println("Ex1")
    if (in == 1) Some("1") else None
  }
}

object Ex2 {
  def unapply(in: Int) : Option[String] = {
    println("Ex2")
    if (in == 2) Some("2") else None
  }
}

val pf : PartialFunction[Int,String] = {
  case Ex1(result) => result
  case Ex2(result) => result
}

val in = 2

if (pf.isDefinedAt(in)) pf(in)
Run Code Online (Sandbox Code Playgroud)

哪个打印

Ex1
Ex2
Ex1
Ex2
res52: Any = 2
Run Code Online (Sandbox Code Playgroud)

在最坏的情况下,您的模式最后匹配,在调用PartialFunction时,您已经两次评估了模式/提取器.当匹配不仅仅是简单的类或列表模式匹配的自定义提取器时,这可能会变得低效(例如,如果您有一个解析XML文档并返回一些值对象的提取器)

PartialFunction#lift遭受同样的双重评估:

scala> pf.lift(2) …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala scala-2.8

13
推荐指数
1
解决办法
883
查看次数

Scala collectFirst函数返回选项[U]

我已经在我正在编写的库中出现过多次这种情况,而且我对目前为止我提出的解决方案并不是特别满意.

假设我有一个昂贵的函数f,它接受一个T类型的项并返回一个类型为Option [U]的值.现在,假设我有一个类型为T的集合,我希望在跨越T的元素执行时检索f返回的第一个非None值,而不是为T的所有元素评估f(如果已找到该值).

我想出的唯一方法是将F包装到Extractor对象中,并将其与scala的collectFirst方法一起使用.

例如:

object FMatch { def unapply(t : T) = f(t) }

collection.collectFirst{ case FMatch(result) => result }
Run Code Online (Sandbox Code Playgroud)

这似乎有点不优雅,我不确定f是否只对每个结果进行一次或两次评估(我还没有测试过这一点).似乎使用一个版本的collectFirst来获取类型为T => Option [U]而不是PartialFunction1 [T]的参数会很有用.

有没有更优雅的方式来做到这一点,我错过了?

optimization scala scala-collections

7
推荐指数
2
解决办法
7932
查看次数

Scala:选择返回Option与PartialFunction的函数

我是一个相对Scala初学者,并希望得到一些关于如何继续实现的建议,看起来可以通过返回Option或PartialFunction的函数来完成.我已经阅读了我能找到的所有相关帖子(参见问题的底部),但这些似乎涉及使用PartialFunction或将其中一个转换为另一个的技术细节; 我正在寻找类型的答案"如果情况是X,Y,Z,那么使用A其他B,但也考虑C".

我的示例用例是使用路径查找器库在位置之间进行路径搜索.假设位置是类型L,路径是类型P,所需的路径搜索结果是Iterable[P].补丁搜索结果应该通过询问所有路径查找器(像Google地图这些可能是自行车,汽车,步行,地铁等等)的路径建议来组装,这些建议可能会或可能不会针对特定的开始/定义结束位置对.

似乎有两种方法可以解决这个问题:

(a)将路径查找器定义为f: (L,L) => Option[P],然后通过类似的方式获得结果finders.map( _.apply(l1,l2) ).filter( _.isDefined ).map( _.get )

(b)将路径查找器定义为f: PartialFunction[(L,L),P] and then get the result via something likefinders.filter(_.isDefined((l1,l2))).map(_.apply((l1,l2)))`

似乎使用函数返回Option[P]将避免对结果进行双重评估,因此对于昂贵的计算,除非有人缓存结果,否则这可能是优选的.似乎使用Option一个可以有一个任意输入签名,而PartialFunction期望一个参数.但是我特别感兴趣的是听到有实际经验的人关于不那么直接,更大的"更大图片"考虑因素,例如与Scala库的交互.使用a PartialFunction会在提供可能以其他方式获得回报的集合API的某些方法方面具有显着优势吗?这样的代码通常会更简洁吗?

相关但不同的问题:

scala option partialfunction

6
推荐指数
1
解决办法
466
查看次数