scala3
scala3 copied to clipboard
Problem with using a ContextFunction1 for +B in PartialFunction[-A, +B].
Compiler version
3.1.2
Description
If you use PartialFunction with ? =>, if you use apply, you will get a Match Error if you pass a key that does not exist.
However, if isDefinedAt or lift is used, it is possible to get the value even if a non-existent key is passed.
Minimized code
use Int => String
@main def Main: Unit =
def pf1: PartialFunction[String, Int => String] = {
case "hoge" => int => int.toString
case "huga" => int => int.toString
}
println(pf1.isDefinedAt("hoge"))
println(pf1.isDefinedAt("huga"))
println(pf1("huga")(1))
println(pf1.unapply("hogehoge"))
println(pf1.isDefinedAt("hogehoge"))
use Int ?=> String
@main def Main: Unit =
def get(using Int): String = summon[Int].toString
def pf2: PartialFunction[String, Int ?=> String] = {
case "hoge" => get
case "huga" => get
}
println(pf2.isDefinedAt("hoge"))
println(pf2.isDefinedAt("huga"))
println(pf2("huga")(using 2))
println(pf2.unapply("hogehoge"))
println(pf2.isDefinedAt("hogehoge"))
Output
use Int => String
[info] true
[info] true
[info] 1
[info] None
[info] false
use Int ?=> String
[info] true
[info] true
[info] 2
[info] Some(Main$package$$anon$2$$Lambda$7/0x0000000800bf0c80@3fb6a447)
[info] true
Expectation
The results with ?=> are similar to those with =>.
Another interesting thing, if you try to apply the returned lambda, you get an error:
println(pf2.unapply("hogehoge").map(x => x(using 3)))
scala.MatchError: hogehoge (of class java.lang.String)
at rs$line$3$.applyOrElse$$anonfun$1(rs$line$3:5)
at rs$line$3$.rs$line$3$$anon$1$$_$applyOrElse$$anonfun$adapted$1(rs$line$3:5)
at rs$line$3$.$init$$$anonfun$1(rs$line$3:11)
at scala.Option.map(Option.scala:242)
... 34 elided
But without map and apply it works.