Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
  • Sep 05 2019 14:43
    @typelevel-bot banned @jdegoes
  • Jan 31 2019 21:17
    codecov-io commented #484
  • Jan 31 2019 21:08
    scala-steward opened #484
  • Jan 31 2019 18:19
    andywhite37 commented #189
  • Jan 31 2019 02:41
    kamilongus starred typelevel/cats-effect
  • Jan 30 2019 00:01
    codecov-io commented #483
  • Jan 29 2019 23:51
    deniszjukow opened #483
  • Jan 29 2019 23:37
  • Jan 29 2019 23:22
  • Jan 29 2019 20:26
    Rui-L starred typelevel/cats-effect
  • Jan 29 2019 18:01
    jdegoes commented #480
  • Jan 29 2019 17:04
    thomaav starred typelevel/cats-effect
  • Jan 28 2019 17:43
    asachdeva starred typelevel/cats-effect
  • Jan 28 2019 07:12
    alexandru commented #480
  • Jan 28 2019 05:45
    codecov-io commented #482
  • Jan 28 2019 05:35
    daron666 opened #482
  • Jan 27 2019 13:56
    codecov-io commented #481
  • Jan 27 2019 13:46
    lrodero opened #481
  • Jan 27 2019 05:47
    codecov-io commented #460
  • Jan 27 2019 05:37
    codecov-io commented #460
Christopher Davenport
My MapRef implementation does.
It's nice to be able to work only at the key level without space leaks.
Operations on individual keys get very complicated for atomicity when the same behavior is required for any modifications from a single key.
Dmitry Polienko


placeStone operation seems complicated(multiple fold and etc) and will take a long time (around 300ms?).

Sync.delay is intended to capture side effects. In your original example mutating grid would, indeed, be a side effect. However a CPU-intensive expression is generally not considered a side effect, so you don't have to delay it. If you want to have a tight control over when it gets evaluated, you should look at Eval in Cats instead.

I am doing it as a practice for Cats effect

In my experience, while tagless final approach (parameterizing with F[_]) seems neat, it tends to also introduce unnecessary complexity. Personally, I try to go with concrete types (Either, IO etc.) first, unless I know I will have to mix domains that require different monad capabilities.

Sean Kwak
@nigredo-tori there is a side effect, mutating the shared map data store from the placestone method
Dmitry Polienko
@cosmir17, In the original example, yes - and that would indeed necessitate a Sync (or some concrete IO-like type). In the one I proposed above, everything is supposed to be immutable (placeStone produces a separate Board value).
Sorry if that was not clear enough.
Sean Kwak
  1. it's a practice for Cat effect.
  2. I am migrating a python code. I don't want to change the design. The logic is complicated. I would like to store the state (data store) inside the class

My MapRef implementation does.

@ChristopherDavenport Thank you, I shall read your test class.

Sean Kwak
Correction* I am migrating a python project
Can I please ask a noddy question?
I get the monad laws and I get that you have to flatMap effects to make them "happen".
What I don't get is: why flatMap? Why can't I, say,. map over an fs2.Stream of effects and have them "executed"? Is the choice of flatMap arbitrary or are there mathematical laws at play here? If so, what are these laws?
Fabio Labella
@PhillHenry I'm not exactly sure what you mean
ultimately an effect is represented as F[A]
so map: F[A] => (A => B) => F[B] cannot execute further effects in the function simply because there are none there
hence why A => F[B] ,which on more fundamental level, it's the general concept of a continuation when you represents effects in this style (programs as values)
you can have other combinators, but they ultimately resolve to flatmap
e.g. with Stream you have evalMap: Stream[F, A] => (A => F[B) => Stream[F, B]
which is flatMap(a => Stream.eval(f(a))
you can find a similar structure to flatMap in strict side-effecting languages as well, if you squint
Fabio Labella

i.e. we look at this capability as primitive

val a = readLine
printLine a

but you can construct it as syntactic sugar over snd : a -> b -> b or more generally next: a -> (a -> b) -> b assuming a strict side-effecting language

similarly to how for comprehensions work with flatMap

@SystemFw I guess as a newbie I don't have the mental model. I've learned by rote that one must flatMap but I can see why after years of mapping over Scala collections one might naively think this:

    val printEffect:  Int => IO[Unit]     = x => IO { println(x) }
    val printEach:    Pipe[IO, Int, Unit] = { _.map(x => printEffect(x)) }
    printEach(Stream(1, 2, 3, 4, 5)).compile.toList

prints out the numbers 1 to 5.
It is, of course, wrong. But why (other than "it just is") is currenlty eluding me.
Can you please expand on why A => F[B] is a program and F[A] => (A => B) => F[B] is not?

Fabio Labella
A => B is not
well, B
your code does not type check
so, the starting point is that println doesn't exist, as you note
println: Unit
what we have is purePrintLn: IO[Unit]
is that clear? (I think it is, but better to check)
btw I'm writing a blog post series on the paradigm, from the ground up, which I think will be helpful eventually
Not sure what you mean by "does not type check". Sure, it's a snipped but I'm running it as we speak.
Yes, a "ground up" blog would help enormously. I look forward to it!
Fabio Labella
you don't have value discard in your options, or the type error will be caught :)
Ah, right! Bad me...
Fabio Labella
you code compile in the same way as def foo: Unit = 3 does
Yes, I see your point
Fabio Labella
but I can break it down ofc
map: F[A] => (A => B) => F[B]
in your case F is Stream
so map: Stream[IO, A] => (A => B) => Stream[IO, B]
A is Int
A => B unifies with Int => IO[Unit]
so your Pipe is Pipe[IO, Int, IO[Unit]]
With you so far.
Fabio Labella
so it emits programs, but doesn't execute them, which btw is useful sometimes! The point of the paradigm is all about being able to juggle doing (execute this now), with being (use this effect as a value, which gets executed "later")
Maybe I am being as thick as a whale omlette but this "it emits programs, but doesn't execute them" is baffling me. What prevents map from executing them?
Fabio Labella
btw I think it's easier if you focus on IO first, because with Stream you have two types at play (Stream and IO), which I think is confusing
look at IO first