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
especially because in current scala if you nest two of those with the same type you get a compile error (which is what you want)
the only thing you need to remember is to make things implicit as close as possible to their call site, which isn't that big of a rule in terms of practical pain (almost none)
Jakub Kozłowski
@kubukoz
generally implicit auto-derivation of algebras becomes really painful for testing as soon as you stub anything
Rob Norris
@tpolecat
There's some subtlety to this that probably deserves a blog post.
Jakub Kozłowski
@kubukoz
Someone™ should write one
Luka Jacobowitz
@LukaJCB
I gotta say I'm a huge fan of
Someone™ , they seem to be doing a ton of work
Long Cao
@longcao
Jakub Kozłowski
@kubukoz
I was about to say something about being ashamed of giving Someone so much to work on
Ryan Zeigler
@rzeigler
Well, the rewards of a job well done and all that
Ryan Zeigler
@rzeigler
so, simpler question, what is the proper name of the >> syntax?
like, *> is to productR
Rob Norris
@tpolecat
Not really simpler, the original names were *> and >>.
People kept asking us to make up a non-symbolic name so we invented productR
Oleg Pyzhcov
@oleg-py
Which is even worse :D
Rob Norris
@tpolecat
:-)
Christopher Davenport
@ChristopherDavenport
Refer to *> and >>. Just easier. I use applicative discard and monadic discard when I’m discussing and people don’t know the symbol.
Ryan Zeigler
@rzeigler
I didn't know if there was a named version at all. *> documentation references produceR, but >> just says its equivalent to flatMap(_ =>
Ryan Zeigler
@rzeigler
for the record, I don't think productR is particularly confusing
maybe I'm weird
Rob Norris
@tpolecat
It's not confusing, just not well know. Everyone who has been doing this for a while will know *> but few would recognize productR.
Ryan Zeigler
@rzeigler
I guess that's fair. When I found that <*> was product, the reason productR is the name for *> made perfect sense
I guess thats more accurately what I meant
Fabio Labella
@SystemFw

There's some subtlety to this that probably deserves a blog post.

What's this ? I lost track

Rob Norris
@tpolecat
@SystemFw the thing where you don't want to introduce instances implicitly but it's probably ok to pass them along implicitly, as long as they're quantified in such a way that you can't really screw it up. For tagless algebras that aren't really typeclasses. ContextShift etc.
Tim McIver
@tmciver
Is this the right place to ask questions about the Scala with Cats book?
Rob Norris
@tpolecat
Sure! If it's specific to the book you may need to contact the authors but if it's about cats then yeah.
Fabio Labella
@SystemFw
@tpolecat ah yeah, sure. It's in my stack, which is very lazily evaluated ;)
Tim McIver
@tmciver

OK. My question is about implementing typeclasses. In the exercise for section 1.3 it shows how to implement syntax and has code like this:

object PrintableSyntax {
  implicit class PrintableOps[A](value: A) {
    def format(implicit p: Printable[A]): String =
      Printable.format(value)

    def print(implicit p: Printable[A]): Unit =
      Printable.print(value)
  }
}

In my implementation, which I did before looking at the answer, was to callformat/print on the implicit p. Is that wrong? Is there a reason to prefer the way above?

Fabio Labella
@SystemFw
what does the above do? add functions to the companion object replicating each method in the typeclass?
(in the part that we don't see)
I would say that the way you did it is actually preferable
or at least more common
Tim McIver
@tmciver
It's to add extension methods to any type that has a Printable instance. The calls above are to methods in the Printable companion object:
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))
}
And my implementation was just:
object PrintableSyntax {
  implicit class PrintableOps[A](a: A) {
    def format(implicit printer: Printable[A]): String = printer.format(a)
    def print(implicit printer: Printable[A]): Unit = println(format)
  }
}
Fabio Labella
@SystemFw
right
that's what I thought
your way is more common
Tim McIver
@tmciver
OK, thanks.
Fabio Labella
@SystemFw
you can add methods to the object as well (I know some people that do it), but it's not really necessary (and adds a bit of boilerplate)
Tim McIver
@tmciver
@SystemFw can you expand on that? Do you mean they add the implicit class to the Printable companion object?
Fabio Labella
@SystemFw
no, I mean exactly what you pasted :)
your first code snippet
they are adding each method that's already present in the Printable typeclass to the printable companion object
do you see it?
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
}