Created
December 22, 2011 13:27
-
-
Save vdichev/1510309 to your computer and use it in GitHub Desktop.
PartialFunction challenge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Let's say I have 2 or more partial functions with different argument types | |
// I'm not interested in the result or the result types here | |
trait Test[A] { val pf: PartialFunction[A,_] } | |
object TestInt extends Test[Int] { val pf: PartialFunction[Int,String] = { case i => i.toString } } | |
object TestString extends Test[String] { val pf: PartialFunction[String,Int] = { case s => s.toInt } } | |
// I want to be able to chain these with orElse: | |
val pf = TestInt.pf orElse TestString.pf | |
// ...except that this doesn't work: neither pf.isDefinedAt(1) nor pf.isDefinedAt("str") work | |
// pf expects Int with String, which looks like a weird creature | |
// What would work is to get to a PartialFunction[Any,_] = { case o: A => … } | |
// for some reasons, I don't want to define it directly like this if I could avoid it | |
// Since Scala compiles this down to something like o.isInstanceOf[A], the obvious hacky solution would be | |
// making the following addition to the trait (if you're allowed to modify it): | |
trait Test[A<:AnyRef] { | |
val pf: PartialFunction[A,_] | |
def pfAny(implicit mf: Manifest[A]): PartialFunction[AnyRef,_] = { | |
// due to erasure, you need to appease both the compiler and the runtime for type A | |
case o: A if mf.erasure.isAssignableFrom(o.getClass) => pf(o) | |
} | |
} | |
// but this gets ugly with our Int-based class: Int doesn't have getClass, so we need Integer | |
object TestInt extends Test[Integer] { | |
val pf: PartialFunction[Integer,String] = { case i => i.toString } | |
} | |
// … not to mention that usage is awful: | |
TestInt.pfAny.apply(1: Integer) | |
// can you do better, ye Scala gods? | |
// isDefinedAt should accept only types of the arguments of the component partial functions |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And yeah, I know there's this wonderful site called StackOverflow; maybe I should try it