I\'m making a simple dependency injection framework, for constructor injection, in Scala. The idea is that objects that are DI\'d put their required services in their constr
trait Construct[T, A] {
def apply(arg: A): T
}
class Constructor[T]{
def apply[A](arg : A)(implicit construct : Construct) = construct(arg)
}
object Constructor {
def apply[T] = new Constructor[T]
}
Constructor[T]("arg")
Type parameter inference in Scala is an all or nothing affair: if you explicitly supply any of the type arguments for a type parameter block then you must supply them all. Consequently, if you want to supply only some of a set of type arguments you must arrange for them to belong to separate type parameter blocks.
The way to do that in this case is to split the construct
method into two stages: the first, which takes an explicit type argument and returns a function-like value; and a second, which applies the function-like value to the arguments for which you want the types to be inferred.
Here's how it might go,
// Function-like type
class Construct1[T] {
def apply[A](arg1: A)(implicit ctor : Constructor1[T, A]): T =
ctor.construct(arg1)
}
def construct[T] = new Construct1[T]
The result of invoking construct[Foo]
is a value of type Construct1[Foo]
. This has an apply
method with a type parameter, which can be inferred, and an implicit parameter whose type is determined by both T
and A
. The invocation you want to make now looks like,
construct[Foo].apply("asd") // T explicit, A inferred as String
Scala's semantic sugaring rules around apply
applies here which mean that this can be rewritten as,
construct[Foo]("asd")
which is exactly the result you want.