3

I saw examples, where a conversion function T => S is passed as an implicit parameter. Scala calls this function view and even provides special syntax sugar -- view bound -- for that case .

However we already have implicit conversions ! Can I replace these views (i.e. conversion functions passed as implicit parameters) with implicit conversions ? ? What I can do with views what I can't with implicit conversions ?

Michael
  • 10,185
  • 12
  • 59
  • 110

2 Answers2

9

My understanding of your question is, what would be the advantage of

case class Num(i: Int)
implicit def intToNum(i: Int) = Num(i)

def test[A <% Num](a: A): Int = a.i
test(33)

over

def test2(a: Num): Int = a.i
test2(33)

Yes? Well the meaning of view is exactly that: the type T can be viewed as another type S. Your method or function might want to deal with T in the first place. An example is Ordered:

def sort[A <% Ordered[A]](x: A, y: A): (A, A) = if (x < y) (x, y) else (y, x)

sort(1, 2)     // --> (1,2)
sort("B", "A") // --> (A,B)

Two more use cases for view bounds:

  • you may want to convert from T to S only under certain circumstances, e.g. lazily (this is in a way the same situation as above: you basically want to work with T)
  • you may want to chain implicit conversions. See this post: How can I chain implicits in Scala?
Community
  • 1
  • 1
0__
  • 66,707
  • 21
  • 171
  • 266
3

What you call implicit conversions is nothing more than a view in global scope.

View bounds are necessary in when using type parameters, as it is a sign that an implicit conversion is necessary. For example:

def max[T](a: T, b: T): T = if (a < b) b else a

Because there's no constrains whatsoever on T, the compiler doesn't know that a < method will be available. Let's see the compiler let you go ahead with that, then consider these two calls:

max(1, 2)
max(true, false)

There's nothing in the signature max[T](a: T, b: T): T that tells the compiler it should not allow the second call, but should allow the first. This is where view bounds come in:

def max[T <% Ordered[T]](a: T, b: T): T = if (a < b) b else a

That not only tells the compiler where the < method comes from, but also tells the compiler that max(true, false) is not valid.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681