Let say we have code snippet below
trait Foo
class Bar extends Foo
def foobar(fn: Option[Set[_ <: Foo] => Unit]) {}
def main(args: Array[String]) {
foobar(Option(bar)) //doesnt compile
}
def bar(input: Set[Bar]) {}
It doest compile because function one is defined as trait Function1 [-T1, +R] extends AnyRef
. My Question is there anyway in Scala to write a function that takes a Type T or its subtype and do something? or as I fear its impossible
You can move the type constraints for the Set
in foobar
out to a type parameter on the function itself:
trait Foo {
class Bar extends Foo
def foobar[A <: Foo](fn: Option[Set[A] => Unit]) {}
def main(args: Array[String]) {
foobar(Option(bar _)) //compiles!
}
def bar(input: Set[Bar]) {}
}
The Scala compiler will infer the type A
from the argument passed into foobar
, while still enforcing the type constraint. Also, you need to partially apply bar
to pass it in an Option
like that.
How about
trait Foo
class Bar extends Foo
def bar(input: Set[_ <: Foo]) {}
def foobar(fn: Option[Set[_ <: Foo] => Unit]) {}
foobar(Some(bar(_))) // partially applied
foobar(None)
You can now do something like this to fully apply foobar() in the Some case
val x = Set(new Bar())
foobar(Some( x => bar(x)))
Note that it has to be x => bar(x) because the type is Some of a function object, not of the function's result.
If you want to use existentials rather than Jesse's answer, you could have something like:
def foobar(fn: Option[(Set[X] => Unit) forSome { type X <: Foo }]) {}
foobar(Option(bar _))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.