You could heavily rely on currrying (and on the fact that Foo.apply
, as any method, will automatically get promoted to a function) and on a little helper to enhance syntax:
object partially {
def apply[A1,A2,R]( f: (A1, A2) => R ) = f.curried
def apply[A1,A2,R]( f: (A1, A2) => R, a1: A1 ) = f.curried( a1 )
def apply[A1,A2,A3,R]( f: (A1, A2, A3) => R ) = f.curried
def apply[A1,A2,A3,R]( f: (A1, A2, A3) => R, a1: A1 ) = f.curried( a1 )
def apply[A1,A2,A3,R]( f: (A1, A2, A3) => R, a1: A1, a2: A2 ) = f.curried( a1 )( a2 )
def apply[A1,A2,A3,A4,R]( f: (A1, A2, A3, A4) => R ) = f.curried
def apply[A1,A2,A3,A4,R]( f: (A1, A2, A3, A4) => R, a1: A1 ) = f.curried( a1 )
def apply[A1,A2,A3,A4,R]( f: (A1, A2, A3, A4) => R, a1: A1, a2: A2 ) = f.curried( a1 )( a2 )
def apply[A1,A2,A3,A4,R]( f: (A1, A2, A3, A4) => R, a1: A1, a2: A2, a3: A3 ) = f.curried( a1 )( a2 )( a3 )
// ... and so on, potentially up to 22 args
}
Then you can do:
scala> val x = partially(Foo)(1)
x: Int => Foo = <function1>
scala> x(2)
res37: Foo = Foo(1,2)
If you really want to use your has
method (instead of just directly applying the function), throw in an implicit classes on top of that:
implicit class Func1Ops[-A,+R]( val f: A => R ) extends AnyVal {
def has( arg: A ): R = f( arg )
}
and now you can do:
scala> val x = partially(Foo)(1)
x: Int => Foo = <function1>
scala> x has 2
res38: Foo = Foo(1,2)