Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Fabio Labella
@SystemFw
object Printable {
  def format[A](input: A)(implicit p: Printable[A]): String =
    p.format(input)

  def print[A](input: A)(implicit p: Printable[A]): Unit =
    println(format(input))
}
this bit
I assume this is the trait
Tim McIver
@tmciver
Yup. OK, I see.
Fabio Labella
@SystemFw
trait Printable[A] {
  def format(input: A): String 
  def print(input: A) : Unit
}
do you also know why they do it?
(if not, I can explain, and I can tell you a more common alternative)
Tim McIver
@tmciver
I think because those methods are automatically imported when the trait is imported . . . ?
Fabio Labella
@SystemFw
the trait is not imported anywhere
Tim McIver
@tmciver
The book probably said but now I forget! :|
Fabio Labella
@SystemFw
ok, so imagine that the syntax bit doesn't exist for a second
say you have
def foo[A](a: A)(implicit p: Printable[A]): String = p.print(a)
makes sense so far?
Tim McIver
@tmciver
Yes
Fabio Labella
@SystemFw
this works, but generally you want to use context bounds because they are less noisy
they are just syntactic sugar so exactly equivalent
def foo[A: Printable](a: A): String = problem.print(a)
your evidence is not named so you can't really use the context bound
do you see?
Tim McIver
@tmciver
By "evidence" you mean the A: Printable part?
Fabio Labella
@SystemFw
you don't know how the Printable evidence is called (the compiler generates a fresh name when you use a context bound)
by "evidence" I mean the p in implicit p: Printable[A]
Tim McIver
@tmciver
OK, I see.
Fabio Labella
@SystemFw
the : Printable in A: Printable is called a context bound
Tim McIver
@tmciver
:thumbsup:
Fabio Labella
@SystemFw
and it's desugared into implicit $mangledCrazyName: Printable[P]
Tim McIver
@tmciver
And you have problem there because we don't have a name for the evidence?
Fabio Labella
@SystemFw
yeah
Tim McIver
@tmciver
Ah, I didn't know that desugaring.
Fabio Labella
@SystemFw
unless you revert to using an explicit implicit myName, which is noisy
however, if you do
object Printable {
  def format[A](input: A)(implicit p: Printable[A]): String =
    p.format(input)

  def print[A](input: A)(implicit p: Printable[A]): Unit =
    println(format(input))
}
you can now do
def foo[A: Printable](a: A): String = Printable.print(a)
Do you see this? (before we go to the next part)
Tim McIver
@tmciver
Yes
Fabio Labella
@SystemFw
so, this works
but it's a bit boilerplate-y, we had to replicate all the methods in the Printable trait also in the Printable object
so you often see a different thing instead
object Printable {
   // summoner
   def apply[A](implicit ev: Printable[A]): Printable[A] = ev
}
that single apply replaces print and format
it just grabs the printable from implicit scope and gives it to you
why?
cause you can do this now
def foo[A: Printable](a: A): String = Printable[A].format(a)

def bar[A: Printable](a: A): Unit = Printable[A].print(a)
without needing to replicate both print and format into the Printable object
does that make sense?
Tim McIver
@tmciver
Because Printable[A] calls the apply method!
Fabio Labella
@SystemFw
yes
Tim McIver
@tmciver
Yes, I've seen this before but now it makes sense!
Fabio Labella
@SystemFw
right, there's two additional pieces of info that should complete the puzzle