These are chat archives for typelevel/cats

20th
Apr 2018
sken
@floreslorca
Apr 20 08:05
i have an scodec question but i come here because the gitter over there is very slow
i just want to know if scodec allows typeclass ie Codec[Message[A]]?
Marko Dimjašević
@mdimjasevic
Apr 20 09:19
Hi everyone. If I have a List[Option[A]], how do I get a List[A] where Nones are filtered out? It's .sequence or something similar, right?
Otto Chrons
@ochrons
Apr 20 09:20
.flatten?
Oleg Pyzhcov
@oleg-py
Apr 20 09:20
from stdlib
Marko Dimjašević
@mdimjasevic
Apr 20 09:24
Yeah, I just figured I could use .flatMap(_.toList), but .flatten is even better. Thanks!
Fabio Labella
@SystemFw
Apr 20 09:33
I disagree that is better fwiw
:P
relies on an implicit conversion from Option to List
Oleg Pyzhcov
@oleg-py
Apr 20 09:35
Well, with cats-mtl you can also do .flattenOption
without reliance on any implicit conversions
just syntax enrichments and type classes :D
Marko Dimjašević
@mdimjasevic
Apr 20 09:56
@SystemFw : how would you do it?
Luka Jacobowitz
@LukaJCB
Apr 20 09:59
I think flatMap(_.toList) is best
Fabio Labella
@SystemFw
Apr 20 10:01
flatMap(_.toList) or foldMap(_.toList), yeah
for me flatten: F[F[A]] => F[A]
Widner
@NOLAnuffsaid
Apr 20 13:21
Morning everyone. I'm having trouble with Reader. I'm consistently getting an ambiguous implicit error. any help would be appreciated.
Oleg Pyzhcov
@oleg-py
Apr 20 13:23
Example might get you help faster
Widner
@NOLAnuffsaid
Apr 20 13:23
working on a link with the code.
  final case class Db(usernames: Map[Int, String], passwords: Map[String, String])

  type DbReader[A] = Reader[Db, A]

  def hasUsername(id: Int): DbReader[Option[String]] =
    Reader(db => db.usernames.get(id))

  def isCorrectPassword(username: String, password: String): DbReader[Boolean] =
    Reader( db => db.passwords.get(username).contains(password))

  def checkLogin(userId: Int, password: String): DbReader[Boolean] =
    for {
      username <- hasUsername(userId)
      result <- username.map( u => isCorrectPassword(u, password) ).getOrElse { false.pure[DbReader] }
    } yield result
there's my code. the part that blows up is the false.pure[DbReader]

FYI

I'm following along in the Scala with Cats book.

Oleg Pyzhcov
@oleg-py
Apr 20 13:39
@NOLAnuffsaid Do you have -Ypartial-unification turned on?
Widner
@NOLAnuffsaid
Apr 20 13:41
yes I do
Oleg Pyzhcov
@oleg-py
Apr 20 13:42
https://scastie.scala-lang.org/4nXvwR9QQV2xXA4jsAo5kg
I had the issue until I enabled partial unification, then everything is working
Widner
@NOLAnuffsaid
Apr 20 13:51
ok i found out why it wasnt working
i didnt have my scalacOptions within my common settings. so I guess it wasnt part of the compiler options for my project build
@oleg-py Thanks for all your help! :smiley:
Oleg Pyzhcov
@oleg-py
Apr 20 17:59

@felher @SystemFw remember that discussion about next level MTL talk? I finally did some shapeless and managed to get boilerplate down to this:

https://github.com/oleg-py/meow-mtl/blob/master/src/main/scala/Test.scala

felher
@felher
Apr 20 18:01
I'm currently on the run with no access to my laptop, but I will take a look at it soon. This is very interesting :) :+1:
Oleg Pyzhcov
@oleg-py
Apr 20 18:03
That's the original snippet btw, to save you some gitter searching: https://scastie.scala-lang.org/ufnXJfszTbKfogVUwf9WVw
Kai(luo) Wang
@kailuowang
Apr 20 18:17
does anyone know why Cats Functor map is almost an order of magnitude faster than manual map?
@State(Scope.Benchmark)
class FooBench {
    val foo = Foo(1)
    @Benchmark
    def mapSyntax(): Foo[String] = foo.map(_.toString)

    @Benchmark
    def reconstruct(): Foo[String] = Foo(foo.toString)
}
case class Foo[A](a: A)
object Foo {
  implicit val functorFor : Functor[Foo] = new Functor[Foo] {
    def map[A, B](fa: Foo[A])(f: A => B): Foo[B] = Foo(f(fa.a))
  }
}
result
[info] Benchmark                                       Mode  Cnt         Score        Error  Units
[info] FooBench.mapSyntax    thrpt   10  81702682.902 ± 464158.559  ops/s
[info] FooBench.reconstruct  thrpt   10  10852269.261 ± 920073.265  ops/s
Adam Rosien
@arosien
Apr 20 18:18
@oleg-py: thanks for the code. i've never been able to get cats-mtl to work, now i have a better example
Travis Brown
@travisbrown
Apr 20 18:25
@kailuowang you meant foo.a.toString in reconstruct?
Kai(luo) Wang
@kailuowang
Apr 20 18:26
yes
oh. wait.
Travis Brown
@travisbrown
Apr 20 18:26
(Foo#toString is going to be super expensive compared to everything else there)
Jose C
@jmcardon
Apr 20 18:26
@kailuowang your foo.toString seems to be operating on the whole case class
and not the A
Kai(luo) Wang
@kailuowang
Apr 20 18:27
it meant to run foo.a.tostring but missed the typo
Jose C
@jmcardon
Apr 20 18:27
I would guess Foo(foo.a.toString) will be significantly faster
Kai(luo) Wang
@kailuowang
Apr 20 18:27
the correct bench is
[info] Benchmark                               Mode  Cnt         Score        Error  Units
[info] timeSeries.bench.FooBench.mapSyntax    thrpt   10   2872799.150 ±  10778.057  ops/s
[info] timeSeries.bench.FooBench.reconstruct  thrpt   10  45958547.951 ± 206265.066  ops/s
so map is significantly slower
if anyone is curious how slow
thanks for spotting the error @travisbrown
Jose C
@jmcardon
Apr 20 18:28
JIT inlining doesnt' play too well with functions
is why I'm guessing that happened
similar to that fold on Either benchmark
Kai(luo) Wang
@kailuowang
Apr 20 18:31
hmm, I spoke too soon again.
I was using a kittens derived functor instance, now testing with a hand-roll instance
the final result
case class Foo[A](a: A)

object Foo {
  implicit val functorFor : Functor[Foo] = new Functor[Foo] {
    def map[A, B](fa: Foo[A])(f: A => B): Foo[B] = Foo(f(fa.a))
  }
}
@State(Scope.Benchmark)
class FooBench {
  val foo = Foo(1)
  @Benchmark
  def mapSyntax(): Foo[Int] = foo.map(_ + 1)

  @Benchmark
  def reconstruct(): Foo[Int] = Foo(foo.a + 1)
}
[info] Benchmark                               Mode  Cnt          Score          Error  Units
[info] FooBench.mapSyntax    thrpt   10  152227908.207 ±   849991.723  ops/s
[info] FooBench.reconstruct  thrpt   10  192014118.432 ± 11927530.169  ops/s
Kai(luo) Wang
@kailuowang
Apr 20 18:36
map syntax is about 25% slower.
Jose C
@jmcardon
Apr 20 18:39
@kailuowang now that you're there, I'm curious about mapSyntax vs a map defined on the obj
so like def map defined on foo vs
Kai(luo) Wang
@kailuowang
Apr 20 18:40
will do that.
Jose C
@jmcardon
Apr 20 18:40
def g[F[_]](f: F[Int]) = f.map(_ + 1)
im kinda curious how much you pay in the map syntax when F is abstract (which I do a lot for abstracting over Effect)
Thanks!
Kai(luo) Wang
@kailuowang
Apr 20 18:44
actually when the function passed in map is less trivial than a _ + 1, e.g. a toString instead, the difference is pretty much negligible.
Jose C
@jmcardon
Apr 20 18:44
whichever you find fit
that's interesting though. if the F methods are basically equivalent that's p nice
Kai(luo) Wang
@kailuowang
Apr 20 19:26