Skip to content

Instantly share code, notes, and snippets.

@vdichev
Created December 22, 2011 13:27
Show Gist options
  • Save vdichev/1510309 to your computer and use it in GitHub Desktop.
Save vdichev/1510309 to your computer and use it in GitHub Desktop.
PartialFunction challenge
// 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
@vdichev
Copy link
Author

vdichev commented Dec 22, 2011

And yeah, I know there's this wonderful site called StackOverflow; maybe I should try it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment