scala - How does orElse work on PartialFunctions -


i getting bizarre behavior (at least seems me) orelse method defined on partialfunction

it seem me that:

val = 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 

makes sense not how behaving , having lot of trouble understanding why types signatures seem indicate exposed above.

here transcript of observing scala 2.11.2:

welcome scala version 2.11.2 (java hotspot(tm) 64-bit server vm, java 1.8.0_11). type in expressions have them evaluated. type :help more information.  scala> val = partialfunction[string, unit] {      | case "hello" => println("bye")      | } a: partialfunction[string,unit] = <function1>  scala> a("hello") bye  scala> a("bye") scala.matcherror: bye (of class java.lang.string)   @ $anonfun$1.apply(<console>:7)   @ $anonfun$1.apply(<console>:7)   @ scala.partialfunction$$anonfun$apply$1.applyorelse(partialfunction.scala:242)   @ scala.runtime.abstractpartialfunction.apply(abstractpartialfunction.scala:36)   ... 33 elided  scala> val b = a.orelse(partialfunction.empty[any, unit]) b: partialfunction[string,unit] = <function1>  scala> b("sdf") scala.matcherror: sdf (of class java.lang.string)   @ $anonfun$1.apply(<console>:7)   @ $anonfun$1.apply(<console>:7)   @ scala.partialfunction$$anonfun$apply$1.applyorelse(partialfunction.scala:242)   @ scala.partialfunction$orelse.apply(partialfunction.scala:162)   ... 33 elided 

note return type of val b has not widen type of partialfunction.

but not work expected:

scala> val c = a.orelse(partialfunction.empty[string, unit]) c: partialfunction[string,unit] = <function1>  scala> c("sdfsdf") scala.matcherror: sdfsdf (of class java.lang.string)   @ $anonfun$1.apply(<console>:7)   @ $anonfun$1.apply(<console>:7)   @ scala.partialfunction$$anonfun$apply$1.applyorelse(partialfunction.scala:242)   @ scala.partialfunction$orelse.apply(partialfunction.scala:162)   ... 33 elided 

there's few things wrong attempt, first let's see working implementation:

scala> val a: partialfunction[string, unit] = { case "hello" => println("bye") } a: partialfunction[string,unit] = <function1>  scala> val b: partialfunction[any, unit] = { case _ => println("fallback") } b: partialfunction[any,unit] = <function1>  scala> val c = a.orelse(b) c: partialfunction[string,unit] = <function1>  scala> c("hello") bye  scala> c("foo") fallback 

there's 2 main errors in code:

  1. the way pf defined
  2. the (wrong) assumption empty "catch-all" function returns nothing

1. how define partialfunction

val right: partialfunction[string, unit] = {   case "hello" => println("bye") } 

how not define it:

val wrong = partialfunction[string, unit] {   case "hello" => println("bye") } 

if @ definition of partialfunction.apply

def apply[a, b](f: => b): partialfunction[a, b] = { case x => f(x) } 

you'll see defines partial function any x , applies given f function it. { case "hello" => println("bye") } f argument, approximately end following (clearly unexpected) partialfunction:

val wrong: partialfunction[string, unit] = {   case x => x match {     case "hello" => println("bye")     } 

so when ask whether it's defined return true, since it's defined any string:

wrong.isdefinedat("hello") // true (ok) wrong.isdefinedat("whatever") // true (sure?) 

but when try apply it

wrong("hello") // bye (ok) wrong("whatever") // matcherror (boom!) 

you fall short on inner match.

since orelse decides whether call "else" depending on result of isdefined, it's obvious why fails.

2. empty catches nothing!

straight docs:

def empty[a, b]: partialfunction[a, b]

the partial function empty domain. attempt invoke empty partial function leads throwing scala.matcherror exception.

the partialfunction (well, it's not partial anymore) you're looking is:

val fallback: partialfunction[any, unit] = { case _ => println("fallback") } 

or - show learn our mistakes -

val fallback = partialfunction[any, unit] { _ => println("fallback") } 

Comments

Popular posts from this blog

java - How to specify maven bin in eclipse maven plugin? -

single sign on - Logging into Plone site with credentials passed through HTTP -

php - Why does AJAX not process login form? -