簡體   English   中英

Scala,部分功能

[英]Scala, partial functions

除了通過case語句之外,有沒有辦法創建PartialFunction

我很好奇,因為我想表達以下內容(scala pseudo ahead!)...

val bi = BigInt(_)
if (bi.isValidInt) bi.intValue

......作為一個部分功能,並做

val toInt : PartialFunction[String, Int] = {
    case s if BigInt(s).isValidInt => BigInt(s).intValue
}

因為我創建了兩次BigInt所以看起來很多余。

不確定我理解這個問題。 但這是我的嘗試:為什么不創建一個提取器?

object ValidBigInt {
  def unapply(s: String): Option[Int] = {
    val bi = BigInt(s)
    if (bi.isValidInt) Some(bi.intValue) else None
  }
}

val toInt: PartialFunction[String, Int] = {
  case ValidBigInt(i) => i
}

另一個選項是(並且可以回答關於是否可以創建除了case文字之外的PartialFunction的問題):

val toInt = new PartialFunction[String, Int] {
  def isDefinedAt(s: String) = BigInt(s).isValidInt
  def apply(s: String) = BigInt(s).intValue
}

然而,由於部分函數的想法是它只是部分定義,最終你仍然會做多余的事情 - 你需要創建一個大的int來測試它是否有效,然后在函數應用程序中創建大的int再次...

我在Github上看到一個項目試圖通過稍微緩存isDefinedAt的結果來解決這個isDefinedAt 如果你進入基准測試,你會發現它比默認的Scala實現要慢:)

因此,如果你想繞過isDefinedAtapply的雙重性質,你應該直接選擇一個提供Option[Int]作為結果的(完整)函數。

我想你正在尋找升降機。 lift取一個部分函數並將其轉換為一個返回Option的函數。 Unlift使用一個返回選項的參數來獲取函數,並返回一個部分函數。

import scala.util.control.Exception._

scala> def fn(s: String) = catching(classOf[NumberFormatException]) opt {BigInt(s)}
fn: (s: String)Option[scala.math.BigInt]

scala> val fnPf = Function.unlift(fn)
fnPf: PartialFunction[String,scala.math.BigInt] = <function1>

scala> val fn = fnPf.lift
fn: String => Option[scala.math.BigInt] = <function1>

密切相關,你也想看看這個答案有關cond和condOpt的信息:

scala> import PartialFunction._
import PartialFunction._

scala> cond("abc") { case "def" => true }
res0: Boolean = false

scala> condOpt("abc") { case x if x.length == 3 => x + x }
res1: Option[java.lang.String] = Some(abcabc)

如果您願意,可以寫出PartialFunctionPartialFunction ”:

object pf extends PartialFunction[Int,String] {
  def isDefinedAt(in: Int) = in % 2 == 0

  def apply(in: Int) = {
    if (in % 2 == 0) 
      "even" 
    else 
      throw new MatchError(in + " is odd")
}

好的,我明白了

import java.lang.NumberFormatException
import scala.util.control.Exception._

val toInt: PartialFunction[String, Int] = {
  catching(classOf[NumberFormatException]) opt BigInt(_) match {
    case Some(bi) if bi.isValidInt => bi.intValue
  }
}

這個怎么樣?

val toInt: PartialFunction[String, Int] = (s: String) => BigInt(s) match {
  case bi if bi.isValidInt => bi.intValue
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM