def m[A, B](x: A, f: A => B): Widget[B] = new Widget(f(x))
def m[A](x: A): Widget[A] = m(x, identity[A])
I’d like to have a single method where f is optional and, when it’s not provided, the method produces a Widget[A]. I’m trying to bring the A =:= B bound into play, but I can’t see how. (I can live with a Curried version of the method where f is implicit, if necessary).
EDIT: This works in Curried form (identity is available implicitly):
def m[A, B](x: A)(implicit f: A => B): Widget[B] = new Widget(f(x))
I don’t know if this will be possible. Possibly with some approach more clever than I am. The big problem you’re going to face is how type inference happens (whole-parameter block at a time, left to right on the type variables).
So doing something like: def m[A, B](x: A, f: A => B = identity[A] _): Widget[B] = new Widget(f(x))
won’t be too satisfactory: m(12) will fail because type parameter B will be inferred to be Nothing. You can make this work if you specify that both A and B are the same though: m[Int, Int](12). However, that’s (to me) more obnoxious than just overloading the function based on arity.
Exactly. I’m not a scala language expert, but it seems like you’re asking something that’s not really possible: infer a type for B when B in this case is only specified by the default polymorphic function in the first parameter group, so you’ll get Nothing.
That’s not how scala’s type variable inference rules work (Haskell would be fine here, but scala != haskell). Common ways i’ve handled this problem are:
use multiple parameter sections
use multiple overloaded methods with differing arities.
Usually one or the other makes more sense depending on the context / use case.
It’s not clear why those are undesirable in your case. Can you elaborate? Or just intellectual curiosity?
Mostly intellectual curiosity. I sometimes deal with bloated Java interfaces with multiple overloading of each method, and I’ve often found that this can be avoided in Scala with default values and implicit arguments (and the absence of primitive types, of course). But I can’t find a way to do it here.
Argument f is an optional transformation of one component of the widget. It’d be nice to have a single method (if you don’t specify a transformation, there is none), but the Curried form feels weird (Currying would feel more natural with the arguments reversed, but then implicit would not work).
Because m(f) as a widget-creating mechanism makes sense to me while m(x) as a virtual widget in wait of a transformation (e.g., component renaming) doesn’t. For the same reason, I would define a Curried map as map(f)(list), never as map(list)(f). It’s probably all subjective (and a holdover of my SML days).
That’s the style in functional languages with auto-curried functions. Scala is an object-functional language with uncurried methods and functions. Therefore the idioms are different.