标签: partialfunction

Scala中的空部分函数

在我看来{ case ... => ... },部分函数的语法至少需要一个case:

scala> val pf: PartialFunction[String, String] = { case "a" => "b" } 
pf: PartialFunction[String,String] = <function1>

scala> val pf: PartialFunction[String, String] = { }                
<console>:5: error: type mismatch;
 found   : Unit
 required: PartialFunction[String,String]
       val pf: PartialFunction[String, String] = { }
                                                 ^
Run Code Online (Sandbox Code Playgroud)

那么,定义"空"部分函数的最佳方法是什么?难道还有比"手动"覆盖更好的办法isDefinedAtapply

scala partialfunction

53
推荐指数
5
解决办法
5685
查看次数

如何将X => Option [R]转换为PartialFunction [X,R]

只要我们有一个PartialFunction[X,R]很容易将它转换为返回的函数Option[R],例如

def pfToOptf[X, R](f: PartialFunction[X,R])(x: X) =
    if (f.isDefinedAt(x)) Some(f(x))
    else None
Run Code Online (Sandbox Code Playgroud)

但是,如果任务相反,那该怎么办:假设我有一个函数作为参数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 }
}
Run Code Online (Sandbox Code Playgroud)

我错过了一些更好的方法吗?

scala partialfunction scala-option

22
推荐指数
3
解决办法
2588
查看次数

撰写部分功能

我有两个PartialFunctions fg.它们没有副作用,可以快速执行.将它们组成另一个部分函数的最佳方法是什么h, h.isDefinedAt(x)iff f.isDefinedAt(x) && g.isDefinedAt(f(x))

如果h函数返回Option而不是部分函数,​​也可以.

我很失望,f andThen g没有做我想做的事:

scala> val f = Map("a"->1, "b"->2)
f: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)

scala> val g = Map(1->'c', 3->'d')
g: scala.collection.immutable.Map[Int,Char] = Map(1 -> c, 3 -> d)

scala> (f andThen g).isDefinedAt("b")
res3: Boolean = true

scala> (f andThen g).lift("b")
java.util.NoSuchElementException: key not found: 2
    at scala.collection.MapLike$class.default(MapLike.scala:228)
Run Code Online (Sandbox Code Playgroud)

monads scala partialfunction maybe

15
推荐指数
1
解决办法
3603
查看次数

如何在Scala中轻松定义更复杂的PartialFunction?

PartialFunctions

PartialFunction简而言之,在Scala中,a 是另外定义isDefinedAt方法的函数.

使用一系列case语句很容易定义部分函数.一个简单的例子是,例如:

scala> val pf: PartialFunction[Int, Unit] = {
     | case 42 => ()
     | }
pf: PartialFunction[Int,Unit] = <function1>

scala> pf.isDefinedAt(42)
res0: Boolean = true

scala> pf.isDefinedAt(0) 
res1: Boolean = false
Run Code Online (Sandbox Code Playgroud)

isDefinedAtcase定义部分函数的s 列表中自动生成.

上下文

Lift框架在许多地方使用部分功能,例如定义一个请求是应该由Lift的引擎处理还是直接从磁盘上的文件提供服务.有时候,我发现自己想要编写一个case匹配所有输入参数的语句,然后才决定是否要返回一个值.这意味着cases 的初始序列不再足以确定我的函数是否定义在给定值

例如,在Lift中,我想添加一个规则,直接提供所有html和htm文件,并且应该处理带有"lift"扩展名的文件.做这样的事情会很容易:

LiftRules.liftRequest.prepend {
  case Req(path, extension, tpe) => extension match {
    case "html" | "htm" => false
    case "lift" => true
  }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,在这种情况下,编译器认为我的部分函数是在任何地方定义的,因为第一个case总是匹配.嵌套match可能与所有传入请求不匹配.而且,请求是不匹配的,MatchError …

scala lift partialfunction

14
推荐指数
1
解决办法
802
查看次数

Scala PartialFunction可以是Monoid吗?

我认为PartialFunction可以是Monoid.我的思维过程是否正确?例如,

import scalaz._
import scala.{PartialFunction => -->}

implicit def partialFunctionSemigroup[A,B]:Semigroup[A-->B] = new Semigroup[A-->B]{
  def append(s1: A-->B, s2: => A-->B): A-->B = s1.orElse(s2)
}

implicit def partialFunctionZero[A,B]:Zero[A-->B] = new Zero[A-->B]{
  val zero = new (A-->B){
    def isDefinedAt(a:A) = false
    def apply(a:A) = sys.error("error")
  }
}
Run Code Online (Sandbox Code Playgroud)

但目前的版本Scalaz(6.0.4)不包括在内.没有包含某些东西的原因是什么?

functional-programming scala partialfunction scalaz monoids

14
推荐指数
1
解决办法
1439
查看次数

在Java中实现Scala PartialFunction的最简单方法是什么?

为了实现互操作性,我需要从Java代码传递Scala PartialFunction.对于Function(Function1等),我可以使用匿名类型对AbstractFunction进行子类化,但对PartialFunction执行相同操作的最简单方法是什么?

在这种情况下,我很乐意将它作为Java中的"完整"函数,出现为所有值定义,但键入为PartialFunction.

java scala partialfunction

12
推荐指数
3
解决办法
2462
查看次数

在Scala中使用andThen链接PartialFunctions

让我们重用Daily scala中的示例:

type PF = PartialFunction[Int,Int]

val pf1 : PF = {case 1 => 2}                      

val pf2 : PF = {case 2 => 3}                      
Run Code Online (Sandbox Code Playgroud)

让我们补充一下:

val pf3 : PF = {case 3 => 4}
Run Code Online (Sandbox Code Playgroud)

然后按预期工作:

pf1 andThen pf2 isDefinedAt(x)
Run Code Online (Sandbox Code Playgroud)

返回trueiff x == 1(实际上,pf2根本不需要是PartialFunction)

但是,我预计:

pf1 andThen pf3 isDefinedAt(x)
Run Code Online (Sandbox Code Playgroud)

将返回false所有x(即,iff pf1已定义,检查pf3),但它不会,只验证pf1.

最后,pf1 andThen pf3 lift(x)总是会导致MatchError.我宁愿得到None ......我可以通过解除每个函数来获得这种行为,pf1.lift(x).flatMap(pf3.lift)但是有没有更简单的方法使用纯PartialFunction API?(并且不单独提升每个部分功能?)

scala partialfunction

10
推荐指数
2
解决办法
3271
查看次数

当与下划线一起使用时,部分函数应用程序会过早地运行代码块

鉴于:

def save(f: => Any)(run:Boolean) { if (run) { println("running f"); f } else println("not running f") } 
Run Code Online (Sandbox Code Playgroud)

我可以用它来调用它:

save("test")(true) -> running f
save("test")(false) -> not running f
save(throw new RuntimeException("boom!"))(false) -> not running f
save(throw new RuntimeException("boom!"))(true) -> running f and then exception thrown
Run Code Online (Sandbox Code Playgroud)

这是部分应用的奇怪行为:

save(throw new RuntimeException("boom!"))(_) -> (Boolean) => Unit = <function1> //as expected
save(throw new RuntimeException("boom!")) _ -> exception thrown
Run Code Online (Sandbox Code Playgroud)

立即评估代码块而不作为函数传递.上述两个陈述有什么区别?

scala currying partialfunction eta-expansion

9
推荐指数
1
解决办法
573
查看次数

orElse如何处理PartialFunctions

我使用orElse定义的方法得到了非常奇怪的行为(至少在我看来)PartialFunction

在我看来:

val a = PartialFunction[String, Unit] {
    case "hello" => println("Bye")
}
val b: PartialFunction[Any, Unit] = a.orElse(PartialFunction.empty[Any, Unit])
a("hello") // "Bye"
a("bogus") // MatchError
b("bogus") // Nothing
b(true)    // Nothing
Run Code Online (Sandbox Code Playgroud)

有道理,但这不是它的表现方式,我很难理解为什么类型签名似乎表明我在上面暴露了什么.

以下是我使用Scala 2.11.2观察的内容的记录:

Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val a = PartialFunction[String, Unit] {
     | case "hello" => println("Bye")
     | }
a: PartialFunction[String,Unit] = <function1> …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala partialfunction read-eval-print-loop

9
推荐指数
1
解决办法
8677
查看次数

Scala,部分功能

有没有办法PartialFunction通过case声明创建一个除外?

我很好奇,因为我想表达以下内容(scala pseudo ahead!)...

val bi = BigInt(_)
if (bi.isValidInt) bi.intValue
Run Code Online (Sandbox Code Playgroud)

......作为一个部分功能,并做

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

因为我创造了BigInt两次似乎是多余的.

scala pattern-matching extractor partialfunction

8
推荐指数
1
解决办法
3987
查看次数