标签: partialfunction

有没有更好的方法在Scala中提升PartialFunction?

我偶尔会遇到以下模式,我基本上有一个PartialFunction[SomeType,AnotherType],并希望将其视为一个Function[SomeType,Option[AnotherType],例如:

def f(s:SomeType):Option[AnotherType] = s match {
  case s1:SubType1 => Some(AnotherType(s1.whatever))
  case s2:SubType2 => Some(AnotherType(s2.whatever))
  case _ => None
}
Run Code Online (Sandbox Code Playgroud)

有没有办法以避免默认情况并将结果包装在Some定义位置的方式编写上述函数?到目前为止我提出的最好的是:

def f(s:SomeType):Option[AnotherType] = pf.lift(s)
def pf:PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在没有定义中间函数的情况下做到这一点?我已经尝试了以下几行,但还没有任何东西可以编译:

def f:Function[SomeType,Option[AnotherType]] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}.lift
Run Code Online (Sandbox Code Playgroud)

functional-programming scala partialfunction

3
推荐指数
1
解决办法
1001
查看次数

在map,flatmap,...部分函数中使用元组

如果我做:

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { t => t._1 + t._2 }
Run Code Online (Sandbox Code Playgroud)

没关系.

如果我做:

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { case (b, n) => b + n }
Run Code Online (Sandbox Code Playgroud)

也没关系.

但如果我这样做:

val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { (b, n) => b + n }
Run Code Online (Sandbox Code Playgroud)

不起作用.
为什么我应该使用"case"关键字来使用命名元组?

scala tuples partialfunction

3
推荐指数
1
解决办法
3753
查看次数

当使用case语句时,isDefinedAt方法如何工作?

在scala中部分函数的这个解释中,case语句使用如下:

val divide2: PartialFunction[Int, Int] = {
    case d: Int if d != 0 => 42 / d
}
Run Code Online (Sandbox Code Playgroud)

然后它说:

虽然此代码未显式实现isDefinedAt方法,但它与前面的除法函数定义完全相同

前面的除法函数显式定义了apply和isDefined方法,如下所示:

    val divide = new PartialFunction[Int, Int] {
    def apply(x: Int) = 42 / x
    def isDefinedAt(x: Int) = x != 0
}
Run Code Online (Sandbox Code Playgroud)

我看到编译器在这里做了一些魔术,但我对机制的本质很好奇:在后台的isDefined体中提取的情况下是守护(如果d!= 0)?多个案例陈述与他们自己的警卫怎么样?函数的域在case语句中定义,因此必须是编译器如何在后台构建isDefined的实现.

我对吗?

scala partialfunction

3
推荐指数
1
解决办法
421
查看次数

PartialFunctions组合的MatchError与orElse

在为Actor编写Specs2规范时,我MatchError对一些部分函数的组合感到有点困惑.

一个最小的例子:

val testPf1 = PartialFunction[Any, Boolean]{ case 2 ? true }
val testPf2 = PartialFunction[Any, Boolean]{ case 1 ? true }
val testPf = testPf1 orElse testPf2
testPf.isDefinedAt(1)
testPf.isDefinedAt(2)
testPf(1)
testPf(2)
Run Code Online (Sandbox Code Playgroud)

导致输出:

testPf1: PartialFunction[Any,Boolean] = <function1>
testPf2: PartialFunction[Any,Boolean] = <function1>
testPf: PartialFunction[Any,Boolean] = <function1>
res0: Boolean = true
res1: Boolean = true
scala.MatchError: 1 (of class java.lang.Integer)
    at com.dasgip.controller.common.informationmodel.programming.parametersequence.A$A161$A$A161$$anonfun$testPf1$1.apply(PFTest.sc0.tmp:33)
    at com.dasgip.controller.common.informationmodel.programming.parametersequence.A$A161$A$A161$$anonfun$testPf1$1.apply(PFTest.sc0.tmp:33)
    at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PFTest.sc0.tmp:243)
    at scala.PartialFunction$OrElse.apply(PFTest.sc0.tmp:163)
    at #worksheet#.#worksheet#(PFTest.sc0.tmp:36)
Run Code Online (Sandbox Code Playgroud)

那让我很困惑.如果对于给定输入isDefinedAt的两个部分函数的组合返回true,我希望我也可以将apply它输出到同一个.

scala partialfunction

3
推荐指数
1
解决办法
158
查看次数

Scala:使用泛型收集

考虑到以下场景

val items = List("a", "b", "c", 1, 2, 3, false, true)
def intItems = items.collect {case i : Int => i}
def stringItems = items.collect {case s : String => s}
Run Code Online (Sandbox Code Playgroud)

有没有办法创建一个通用函数来处理这种行为?

我尝试了以下方法

def itemsAs[T]: List[T] = items.collect { case item: T => item } 
Run Code Online (Sandbox Code Playgroud)

itemsAs[Int] 
Run Code Online (Sandbox Code Playgroud)

回报

List[Int]] = List(a, b, c, 1, 2, 3, false, true)
Run Code Online (Sandbox Code Playgroud)

另一种方法是提供partial functionas 参数,但仍然必须复制case i: Int => iand case s: String => s。有没有办法让它变得更紧凑?谢谢

generics scala partialfunction

3
推荐指数
1
解决办法
282
查看次数

Scala关于F#中"部分函数"和".orElse"方法的概念

在Scala中,"部分功能"的概念与F#的function关键字允许我实现的功能非常相似.然而,Scala的部分函数也允许通过orElse如下所示的方法进行合成:

def intMatcher: PartialFunction[Any,String] = {
  case _ : Int => "Int"
}

def stringMatcher: PartialFunction[Any,String] = {
  case _: String => "String"
}

def defaultMatcher: PartialFunction[Any,String] = {
  case _ => "other"
}

val msgHandler =
  intMatcher
  .orElse(stringMatcher)
  .orElse(defaultMatcher)

msgHandler(5) // yields res0: String = "Int"
Run Code Online (Sandbox Code Playgroud)

我需要知道是否有办法在F#中实现相同的组合功能.

f# scala partialfunction

3
推荐指数
2
解决办法
186
查看次数

Why does providing a partial function to map throw at runtime rather than give a compile error?

Apologies if this is obvious but I am new to scala and I am getting two unexpected behaviors with the following code:

Seq(1, "a", 2, "b") map { 
    case i: Int => i+1
}
Run Code Online (Sandbox Code Playgroud)

1) I would have expected to get back a collection where the strings are unchanged and the numbers are incremented by 1 but instead I get an error.

2) I believe the case i: Int => i + 1 syntax represents a partial function which is …

scala partialfunction

3
推荐指数
1
解决办法
66
查看次数

如何使用PartialFunction.applyOrElse

我有一个PartialFuncton[Throwable,Future[Result]]名为errorMap的函数,用于将throwable转换为结果或将来失败.我可以通过做liftgetOrElse这样的:

val x: Future[Result] = errorMap.lift(e).getOrElse(Future.failed(e))
Run Code Online (Sandbox Code Playgroud)

我认为同样应该可以实现applyOrElse,但我似乎无法弄清楚如何调用它来实现这一目标.我误解了什么applyOrElse是为了什么?

scala partialfunction

2
推荐指数
1
解决办法
2081
查看次数

Scala函数部分应用

我试图了解函数部分应用程序在 Scala 中的工作原理。

为此,我构建了这个简单的代码:

object Test extends App {
  myCustomConcat("General", "Public", "License") foreach print

  GeneralPublicLicenceAcronym(myCustomConcat(_)) foreach print

  def myCustomConcat(strings: String*): List[Char] = {
    val result = for (s <- strings) yield {
      s.charAt(0)
    }

    result.toList
  }


  def GeneralPublicLicenceAcronym (concatFunction: (String*) => List[Char] ) = {

    myCustomConcat("General", "Public", "License")
  }
}
Run Code Online (Sandbox Code Playgroud)

myCostumConcat函数接受输入一个字符串数组,并返回一个包含每个字符串的第一个字母的列表。

所以,代码

myCustomConcat("General", "Public", "License") foreach print
Run Code Online (Sandbox Code Playgroud)

将在控制台上打印:GPL

现在假设我想编写一个函数来生成 GPL 缩写词,使用(作为输入参数)我之前的函数提取每个字符串的第一个字母:

def GeneralPublicLicenceAcronym (concatFunction: (String*) => List[Char] ): List[Char] = {

    myCustomConcat("General", "Public", "License")
  }
Run Code Online (Sandbox Code Playgroud)

使用部分应用程序运行这个新函数: …

scala partialfunction

2
推荐指数
1
解决办法
456
查看次数

在 Scala 中使用运算符 orElse 的正确方法是什么?

我想写两个服务,然后用orElse让两个服务组合在一起,即service_one或service_two。它们都是偏函数。

服务一是:

val usersService = HttpService {
case request @ GET -> Root / "users" / IntVar(userId) =>
  Ok("test")
}
Run Code Online (Sandbox Code Playgroud)

服务二是:

val versionService = HttpService{
  case req @ GET -> Root / "version" => {
    val jsonmap = ("origin" -> req.remoteAddr.getOrElse("unknown ip"))
    Ok(compact(render(jsonmap)))
   }
}
Run Code Online (Sandbox Code Playgroud)

然后我想把它们结合在一起。

val service = userService orElse versionService   //the error happens here.
Run Code Online (Sandbox Code Playgroud)

错误是:

[error] F:\workspace\frankcheckAPI\src\main\scala\com\cardaccess\ServiceApp.scala:46: value orElse is not a member of org.http4s.HttpService
[error]   val service = usersService orElse versionService
[error]                              ^
[error] one …
Run Code Online (Sandbox Code Playgroud)

scala operators partialfunction

2
推荐指数
1
解决办法
1万
查看次数