- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Optional implicits in Scala?
Mon, 2010-12-06, 10:39
Might it be a nice feature for scala to have Optional implicits: for example:
class Foo[A] { def bar(implicit n : Option[Numeric[A]]) }
The compiler could inject an implicit value if one were found, and None otherwise. The reason for this is that I would like to make checks conditional on a typeclass being found and it seems to me that such functionality would possibly be useful. The exact use-case I have in mind is the following:
I'm trying to implement a MyRange class which works on anything which can be Ordered:
This is meant to represent contiguous ranges which may or may not be closed at their extremities and which may (or may not) be bounded. For example:
[1.2, 3.5) : MyRange[Double](-∞, 0) : MyRange[Int]
I want to have a typeclass called "Increment"
and implementations for discrete types:
But then for any discrete type D and any instance d, the range: (d, increment(d)) is invalid (that is, it should be a runtime exception to create such a range). So I would like to have a method to be called in the MyRange constructor:
Is this a terrible idea? Are there other ways of achieving my goal?
Chris
class Foo[A] { def bar(implicit n : Option[Numeric[A]]) }
The compiler could inject an implicit value if one were found, and None otherwise. The reason for this is that I would like to make checks conditional on a typeclass being found and it seems to me that such functionality would possibly be useful. The exact use-case I have in mind is the following:
I'm trying to implement a MyRange class which works on anything which can be Ordered:
class MyRange[O : Ordered]
This is meant to represent contiguous ranges which may or may not be closed at their extremities and which may (or may not) be bounded. For example:
[1.2, 3.5) : MyRange[Double](-∞, 0) : MyRange[Int]
I want to have a typeclass called "Increment"
trait Increment[I] { def increment(i : I) : I}
and implementations for discrete types:
implicit val IntIncrement { def increment(i : Int) = i + 1 }implicit val MyDateIncrement { def increment(i : MyDate) = myDate addDays 1 }
But then for any discrete type D and any instance d, the range: (d, increment(d)) is invalid (that is, it should be a runtime exception to create such a range). So I would like to have a method to be called in the MyRange constructor:
def validateDiscrete(implicit i : Option[Increment[A]]) = i.foreach(ii => require(ii.increment(lowerBound) < upperBound)))
Is this a terrible idea? Are there other ways of achieving my goal?
Chris
Mon, 2010-12-06, 11:27
#2
RE: Optional implicits in Scala?
Awesome!
> Date: Mon, 6 Dec 2010 10:45:59 +0100
> Subject: Re: [scala-internals] Optional implicits in Scala?
> From: jzaugg@gmail.com
> To: oxbow_lakes@hotmail.com
> CC: scala-internals@listes.epfl.ch
>
> Implicit parameters can have defaults.
>
> scala> implicit def OptionalImplicit[A <: AnyRef](implicit a: A =
> null) = Option(a)
> OptionalImplicit: [A <: AnyRef](implicit a: A)Option[A]
>
> scala> implicitly[Option[Ordering[Int]]]
> res0: Option[Ordering[Int]] = Some(scala.math.Ordering$Int$@1443628)
>
> scala> implicitly[Option[Ordering[Any]]]
> res1: Option[Ordering[Any]] = None
>
> -jason
>
> Date: Mon, 6 Dec 2010 10:45:59 +0100
> Subject: Re: [scala-internals] Optional implicits in Scala?
> From: jzaugg@gmail.com
> To: oxbow_lakes@hotmail.com
> CC: scala-internals@listes.epfl.ch
>
> Implicit parameters can have defaults.
>
> scala> implicit def OptionalImplicit[A <: AnyRef](implicit a: A =
> null) = Option(a)
> OptionalImplicit: [A <: AnyRef](implicit a: A)Option[A]
>
> scala> implicitly[Option[Ordering[Int]]]
> res0: Option[Ordering[Int]] = Some(scala.math.Ordering$Int$@1443628)
>
> scala> implicitly[Option[Ordering[Any]]]
> res1: Option[Ordering[Any]] = None
>
> -jason
>
Mon, 2010-12-06, 11:37
#3
Re: Optional implicits in Scala?
On Mon, Dec 6, 2010 at 11:20 AM, Chris Marshall <oxbow_lakes@hotmail.com> wrote:
Awesome!
Indeed it is. Beware tho, it's a tad harder to debug when you _think_ you have the implicit in scope and you really don't.
> Date: Mon, 6 Dec 2010 10:45:59 +0100
> Subject: Re: [scala-internals] Optional implicits in Scala?
> From: jzaugg@gmail.com
> To: oxbow_lakes@hotmail.com
> CC: scala-internals@listes.epfl.ch
>
> Implicit parameters can have defaults.
>
> scala> implicit def OptionalImplicit[A <: AnyRef](implicit a: A =
> null) = Option(a)
> OptionalImplicit: [A <: AnyRef](implicit a: A)Option[A]
>
> scala> implicitly[Option[Ordering[Int]]]
> res0: Option[Ordering[Int]] = Some(scala.math.Ordering$Int$@1443628)
>
> scala> implicitly[Option[Ordering[Any]]]
> res1: Option[Ordering[Any]] = None
>
> -jason
>
--
Viktor Klang,
Code Connoisseur
Work: Scalable Solutions
Code: github.com/viktorklang
Follow: twitter.com/viktorklang
Read: klangism.tumblr.com
Mon, 2010-12-06, 13:57
#4
Re: Optional implicits in Scala?
Btw- when searching for option[T] the compiler Will look in the companion object for T. Combine this with the fact that default parameters have lower precedence and you can do:
def foo[A](implicit value : Option[A] = None) = value
trait Foo
object Foo {
implicit def Makefoo = Some(new Foo {})
}
foo[Bar] // None
foo[Foo] // Some(Foo)
This could help remove the need for importing implicits to a particular scope. Note that imported implicits should override what's available from companion/package objects. So it's a pretty flexible system
On Dec 6, 2010 5:35 AM, "√iktor Klang" <viktor.klang@gmail.com> wrote:
On Mon, Dec 6, 2010 at 11:20 AM, Chris Marshall <oxbow_lakes@hotmail.com> wrote:
Awesome!
Indeed it is. Beware tho, it's a tad harder to debug when you _think_ you have the implicit in scope and you really don't.
>
>
> > Date: Mon, 6 Dec 2010 10:45:59 +0100
> > Subject: Re: [scala-internals] Optional implicits ...
--
Viktor Klang,
Code Connoisseur
Work: Scalable Solutions
Code: github.com/viktorklang
Follow: twitter.com/viktorklang
Read: klangism.tumblr.com
Mon, 2010-12-06, 14:07
#5
Re: Optional implicits in Scala?
On Mon, Dec 6, 2010 at 1:51 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Btw- when searching for option[T] the compiler Will look in the companion object for T. Combine this with the fact that default parameters have lower precedence and you can do:
def foo[A](implicit value : Option[A] = None) = value
trait Foo
object Foo {
implicit def Makefoo = Some(new Foo {})
}foo[Bar] // None
foo[Foo] // Some(Foo)This could help remove the need for importing implicits to a particular scope. Note that imported implicits should override what's available from companion/package objects. So it's a pretty flexible system
Yeah, it's powerful, we use it for automatic sender tracking in Akka
On Dec 6, 2010 5:35 AM, "√iktor Klang" <viktor.klang@gmail.com> wrote:
On Mon, Dec 6, 2010 at 11:20 AM, Chris Marshall <oxbow_lakes@hotmail.com> wrote:
Awesome!
Indeed it is. Beware tho, it's a tad harder to debug when you _think_ you have the implicit in scope and you really don't.
>
>
> > Date: Mon, 6 Dec 2010 10:45:59 +0100
> > Subject: Re: [scala-internals] Optional implicits ...
--
Viktor Klang,
Code Connoisseur
Work: Scalable Solutions
Code: github.com/viktorklang
Follow: twitter.com/viktorklang
Read: klangism.tumblr.com
--
Viktor Klang,
Code Connoisseur
Work: Scalable Solutions
Code: github.com/viktorklang
Follow: twitter.com/viktorklang
Read: klangism.tumblr.com
Implicit parameters can have defaults.
scala> implicit def OptionalImplicit[A <: AnyRef](implicit a: A =
null) = Option(a)
OptionalImplicit: [A <: AnyRef](implicit a: A)Option[A]
scala> implicitly[Option[Ordering[Int]]]
res0: Option[Ordering[Int]] = Some(scala.math.Ordering$Int$@1443628)
scala> implicitly[Option[Ordering[Any]]]
res1: Option[Ordering[Any]] = None
-jason
2010/12/6 Chris Marshall :
> Might it be a nice feature for scala to have Optional implicits: for
> example:
> class Foo[A] {
> def bar(implicit n : Option[Numeric[A]])
> }
> The compiler could inject an implicit value if one were found, and None
> otherwise. The reason for this is that I would like to make checks
> conditional on a typeclass being found and it seems to me that such
> functionality would possibly be useful. The exact use-case I have in mind is
> the following:
> I'm trying to implement a MyRange class which works on anything which can be
> Ordered:
>
> class MyRange[O : Ordered]
>
> This is meant to represent contiguous ranges which may or may not be closed
> at their extremities and which may (or may not) be bounded. For example:
> [1.2, 3.5) : MyRange[Double]
> (-∞, 0) : MyRange[Int]
> I want to have a typeclass called "Increment"
>
> trait Increment[I] {
> def increment(i : I) : I
> }
>
> and implementations for discrete types:
>
> implicit val IntIncrement { def increment(i : Int) = i + 1 }
> implicit val MyDateIncrement { def increment(i : MyDate) = myDate addDays 1
> }
>
> But then for any discrete type D and any instance d, the range: (d,
> increment(d)) is invalid (that is, it should be a runtime exception to
> create such a range). So I would like to have a method to be called in the
> MyRange constructor:
>
> def validateDiscrete(implicit i : Option[Increment[A]]) = i.foreach(ii =>
> require(ii.increment(lowerBound) < upperBound)))
>
> Is this a terrible idea? Are there other ways of achieving my goal?
> Chris