out of curiosity, I was wondering if it was possible to do something like :
def myMethod(
a: Option[A] = None,
b: Option[B] = None,
...
z: Option[Z] = None
): Something = {
...
}
What I want is not to have to call it that way:
myMethod(
b = Some(newB),
m = Some(newM)
)
but instead being able to just do myMethod(b = newB, m = newM) without having to always convert A to Some(a).
Is it possible ?
Possible, yes:
object Test {
implicit def anythingToOption[A](a: A): Option[A] = Option(a)
def foo(something: Option[Int]): Unit = ???
def main(args: Array[String]): Unit = {
foo(1)
}
}
Should you do this? NO. Why? Because implicits with such broad scopes are dangerous. For one, they can lead to ambiguity when you actually need a relevant implicit in scope. Second, when someone reads this, they'll need to see where this conversion happens, and why. Third, this can lead to subtle bugs.
Instead, you can use extension methods, whether you get them from the Cats library or write them yourself:
object Test {
implicit class OptionOps[A](val a: A) extends AnyVal {
def toOption: Option[A] = Option(a)
def some: Option[A] = Some(a)
}
def foo(something: Option[Int]): Unit = ???
def main(args: Array[String]): Unit = {
foo(1.toOption)
foo(1.some)
}
}
My favorite solution is this:
class Opt[A](val value: Option[A]) extends AnyVal
object Opt {
implicit def fromA[A](x: A): Opt[A] = new Opt(Some(x))
implicit def toOption[A](x: Opt[A]): Option[A] = x.value
def N[A]: Opt[A] = new Opt(None)
}
def myMethod(
a: Opt[A] = Opt.N,
...
z: Opt[Z] = Opt.N
): Something = ...
Because Opt is used only for default parameters, the implicit conversions are harmless.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With