Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 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
Fabio Labella
@SystemFw
works mostly in conjunction with typeclasses
Steven Fines
@sfines-clgx
the best notation is abused notation
Fabio Labella
@SystemFw
def length[F[_]: Foldable, A]](l: F[A]): Int
that's the real type
so these are the mechanics basically
Steven Fines
@sfines-clgx
the cats Foldable typeclass
Fabio Labella
@SystemFw
yep
trait Foldable[F[_]] { 
  ...
now, on to the pattern
this pattern (which I'm about to show) is part of a class of encodings called final tagless encodings
Steven Fines
@sfines-clgx
ok
Fabio Labella
@SystemFw
so you hear referred as "final tagless"
I have a long explanation on what final tagless means in general, you can look it up at https://systemfw.org/writings
so I'll just explain the actual pattern we use
Steven Fines
@sfines-clgx
bookmarked
Fabio Labella
@SystemFw
which could call "capability traits" or "capability classes" or whatever
the basic idea is that the types that we use for effects, have shape F[_]
this includes IO, primarily
but monad transformer as well
the idea is akin to interface and implementation
Steven Fines
@sfines-clgx
alright
Fabio Labella
@SystemFw
when you have things like
def print(s: String): IO[Unit]
def read: IO[String]

def echo: IO[Unit] = read.flatMap(print)
you want to:
  • describe the domain of effects (just like you use data types to describe the domain of data)
  • have a testable/swappable implementation
  • (additionally, sometimes) increase the generality of echo to be used with many different effects (like a traced IO effect)
and you do it like that
Steven Fines
@sfines-clgx
you would have a trait that defines those in terms of expecting some manner of effect type
Fabio Labella
@SystemFw
trait Console[F[_]] {
  def print(s: String): F[Unit]
  def read: F[String]
}
object Console {
  def apply[F[_]](implicit ev: Console[F]) = ev

  def std: Console[IO] = new Console[IO] {
     def print(s: String): IO[Unit] = ...
     def read: IO[String] = ...
  }
}
then your "programs", like echo are written as
def echo[F[_]: Console: Monad]: F[Unit] = Console[F].read.flatMap(Console[F].print)
Steven Fines
@sfines-clgx
ok
Fabio Labella
@SystemFw
this is achieves all thee goals above, and it composes nicely with other things
e.g. if you have def fetch[F[_]: Cache]: F[User]
you might use them both and get def logic[F[_]: Console: Cache]
then at some point (typically close to main)
you will have
implicit val console = Console.std
implicit val cache = ...


logic[IO]
and "inject" the implementation (or interpret the language, in more FP terms)
this is going to be very nice in scala 3
given Console[IO] = Console.std
...

logic[IO]
Steven Fines
@sfines-clgx
I get the feeling that I will be re-learning scala when scala 3 comes around
Fabio Labella
@SystemFw
also, very often the constructor of things like Console have shape F[Thing[F]] or Resource[F, Thing[F]]
and that's it
it's a way of structuring programs
the OO view is interface + implementation and dependency injection
Steven Fines
@sfines-clgx
ah, k.
I come to this from almost 30 years of OOP
so this is a change
Fabio Labella
@SystemFw
the FP view is that you're constructing a "language" to write your programs in, one that represents your domain in a way that makes the problem you have easy to solve, and then you interpret this language
trait Console[F[_]] this are called "algebras", in the jargon
(well, lots of things are called algebras, again, abuse of notation compared to the math this came from, which btw is not category theory, in this case)
Steven Fines
@sfines-clgx
no, it's like Lie algebras or other analytical algebras
Fabio Labella
@SystemFw
it's actually fairly simple though, and a really really nice way to structure programs due to Scala's unique features (even when compared to Haskell or Rust)