These are chat archives for typelevel/cats

11th
Dec 2017
Andi Miller
@andimiller
Dec 11 2017 01:34
is there a trick to make intellij not complain about mapN on a tuple3?
Jose C
@jmcardon
Dec 11 2017 01:34
+1 to that question actually
Same issue here
Andi Miller
@andimiller
Dec 11 2017 01:35
I just resorted to this
  // this is here to make IntellIJ complain less
  def buildMainArgs(
      t: (Validated[String, FlatMapServiceConfiguration[C]],
          Validated[String, Stream[E, I]],
          Validated[String, Sink[E, O]]))
    : Validated[String,
                (FlatMapServiceConfiguration[C], Stream[E, I], Sink[E, O])] =
    catsSyntaxTuple3Semigroupal(t).mapN(Tuple3.apply)
and it's terrible
but it stops being red
Jose C
@jmcardon
Dec 11 2017 01:38
oh lord I'd rather just leave it redlined
Andi Miller
@andimiller
Dec 11 2017 01:38
it redlined 200 lines of my code
Jose C
@jmcardon
Dec 11 2017 01:52
holy moly
Rob Norris
@tpolecat
Dec 11 2017 02:33
IDEs for Scala are a failure. I think we should give up and put our weight behind the LSP server in sbt.
It’s the only thing I have ever used that’s even remotely reliable
Andi Miller
@andimiller
Dec 11 2017 02:34
how much info does that give you? does it just mark compilation errors?
Rob Norris
@tpolecat
Dec 11 2017 03:06
Yes, and it can go to class definitions. Very basic but it never lies.
andy scott
@andyscott
Dec 11 2017 04:39
@tpolecat how do I set this up?
Rob Norris
@tpolecat
Dec 11 2017 04:40
Use sbt 1.1.0-RC1, vs-code with Scala (sbt) plugin.
Start sbt then open the project in vs-code.
The ease of setup got my attention. No screwing around with computer shit.
andy scott
@andyscott
Dec 11 2017 04:47
whoa
Looks like a pretty simple implementation behind the scenes
andy scott
@andyscott
Dec 11 2017 05:04
Looking forward to givint this a go
zero_coder
@kostonstyle
Dec 11 2017 07:39
@jmcardon thanks for your answer. Could it happen stackoverflow on my code above?
Daniel Miranda
@danielkza
Dec 11 2017 13:18

Hello folks! I'm starting a new project with Cats, and ran into a bit of a roadblock using Eval.
Basically, I'm trying to define a type-safe map, whose values may be strictly or lazily defined, such that some values may be derived from others, while others are constants. I would like to memoize already computed values, hence Eval seemed like a good candidate.

Unfortunately, I can't seem to find a way to have the lazy Eval instances have my Environment as an input of their computation. If I simply store an Eval[T], when defining lazy keys they will capture the Environment by value, and never make use of any future updates. If I store a function of Environment => Eval[T] I dodge that problem, but I lose memoization, as Eval will memoize the function itself and not the result of it's execution.

Is there a good solution that does not involve a) re-constructing the whole map with new Eval instances with every update b) Re-implementing something similar to Eval to account for the Environment?

This is what I have so far (which admittedly isn't much). Thanks in advance.

import cats.Eval

object Environment {
  final case class Key[T] (name: String) {
    type Value = T
  }

  sealed trait Value[T] {
    def get(env: Environment): Eval[T]
  }
  case class Constant[T](value: T) extends Value[T] {
    override def get(env: Environment): Eval[T] = Eval.now(value)
  }
  case class Derived[T](f: Environment => Eval[T]) extends Value[T] {
    override def get(env: Environment): Eval[T] = f(env)
  }

  val empty: Environment =
    new MapEnvironment(Map.empty)

  class MapEnvironment(private val backing: Map[Key[_], Value[_]]) extends Environment {
    override def get[T](key: Key[T]): Option[Eval[T]] = {
      for {
        value <- backing.get(key)
      } yield value.get(this).map(_.asInstanceOf[T])
    }

    override def put[T](key: Key[T], value: Value[T])(implicit ev: T =:= key.Value): Environment = {
      new MapEnvironment(backing + (key -> value))
    }

    override def -[T](key: Key[T]): Environment =
      new MapEnvironment(backing - key)
  }
}

sealed trait Environment {
  import Environment._

  def get[T](key: Key[T]): Option[Eval[T]]

  def put[T](key: Key[T], value: Value[T])(implicit ev: T =:= key.Value): Environment

  def +[T](t: (Key[T], Value[T])): Environment =
    put(t._1, t._2)

  def +[T](t: (Key[T], Eval[T]))(implicit dummy: DummyImplicit): Environment =
    put(t._1, Derived(_ => t._2))

  def +[T](t: (Key[T], T))(implicit dummy: DummyImplicit, dummy2: DummyImplicit): Environment =
    put(t._1, Constant(t._2))

  def -[T](key: Key[T]): Environment
}
Andrea
@Andrea
Dec 11 2017 16:55
hi there, I have a little question, where does the website for cats live?
Andi Miller
@andimiller
Dec 11 2017 16:57
it's in the docs module
Andrea
@Andrea
Dec 11 2017 16:58
thanks :D
Alexander Konovalov
@alexknvl
Dec 11 2017 16:59
whoa, there is a youtube channel for cats - https://www.youtube.com/Videosforyourcat
:trollface:
Andrea
@Andrea
Dec 11 2017 17:04
If we were to work on this typelevel/cats#1017 is this still useful?
Alexander Konovalov
@alexknvl
Dec 11 2017 17:17
More documentation is always good.
Andrea
@Andrea
Dec 11 2017 17:25
cool, is it ok to push PRs that are WIP to get some comments?
Rob Norris
@tpolecat
Dec 11 2017 17:26
Yes
Andrea
@Andrea
Dec 11 2017 17:27
Cool, thanks
andy scott
@andyscott
Dec 11 2017 17:56
Are there any benchmarks floating around for cats.free.Free?
Elliot Stern
@PipocaQuemada
Dec 11 2017 21:32
Where does the Monad[IO] instance live in cats-effect 0.4?
Effect is a subtype of Monad
See the light orange lozenges here https://github.com/tpolecat/cats-infographic
Christopher Davenport
@ChristopherDavenport
Dec 11 2017 21:45
@PipocaQuemada If you need it explicitly(hopefully you don’t) its in IO.ioEffect
ChristopherDavenport @ChristopherDavenport pipes repetitive information for no reason...