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
Steven Fines
@sfines-clgx
k
Fabio Labella
@SystemFw
for example Option, defined as Option[A], needs to know what A is
in other words, Option has kind * -> *, because it requires a proper type (say Int), and it gives you another proper type Option[Int]
Either is of kind * -> * -> * (they are curried, so you can think of it as having two arguments)
Steven Fines
@sfines-clgx
because it takes a single proper type and returns a coproduct of two types?
Fabio Labella
@SystemFw
because it needs to have two proper types as arguments, to give you a proper type, say Int and String, and it gives you Either[Int, String]
Steven Fines
@sfines-clgx
ok
Fabio Labella
@SystemFw
just like a curried function Int => Int => Int can be seen as taking two ints
this language is quite rich, e.g. the kind of Resource is (* -> *) -> * -> *
it takes a first argument of kind * -> * and a second of kind * and it gives you something of kind *
e.g. Resource[IO, Int]
Steven Fines
@sfines-clgx
in this context -> is sort of a mapping operator?
Fabio Labella
@SystemFw
it's like a function in this notation (this is haskell notation, I'm going to show you the scala one in a sec)
a function on types, almost
Steven Fines
@sfines-clgx
Ok, that makes it clearer
Fabio Labella
@SystemFw
IO is of kind * -> *, so Resource[IO, Int] kind checks
Resource[Int, Int] is a kind error on the first argument
Resource[IO, List] is a kind error on the second argument
does that make sense?
Steven Fines
@sfines-clgx
yeah, I'm following
Fabio Labella
@SystemFw
cool, now scala notation
type parameters of kind * -> * are represented as F[_]
things with one "hole"
fits IO, List and Option, but not Int or Resource
type parameters in the shape of Either are represented as F[_, _]
two holes
Steven Fines
@sfines-clgx
so container types
for F[_]
Fabio Labella
@SystemFw
yeah, "container types" is a bit a misnomer, we don't think of them as containers (IO is not a container)
we call them "effects"
Steven Fines
@sfines-clgx
ok, I can use that term
Fabio Labella
@SystemFw
types like Resource , which have kind (* -> *) -> * -> *have shape F[_[_], _]: two holes, one of which is G[_] shaped (kind * -> *), and one is A shaped (kind *),
all good?
we can move to an example now
Steven Fines
@sfines-clgx
yeah
this notation in scala would need the kind-projector plugin?
Fabio Labella
@SystemFw
no
that's normal scala
kind projector is needed (in scala 2) to partially apply types
e.g to say that Either String fits into F[_]
which is written Either[String, *]
Steven Fines
@sfines-clgx
right, ok. that clarifies the utility there
Fabio Labella
@SystemFw
also, kind projector is also syntax for normal (albeit obscure) scala, but we'll treat it as a black box here
Steven Fines
@sfines-clgx
sure
Fabio Labella
@SystemFw
so let's say you have def length(l: List[Int]): Int and def length(l: List[String]): String
you can represent both as def length[A](l: List[A]): Int
this is called parametric polymorphism ("generics")
hopefully familiar
Steven Fines
@sfines-clgx
right, and that part I get pretty well since I learned it way back in the C++ days
Fabio Labella
@SystemFw
but let's say you have
def length[A](l: List[A]): Int
def length[A](l: Tree[A]): Int