checking into fs2 tutorial, I stumbled upon the following code
def client[F[_]: MonadCancelThrow: Console: Network]: F[Unit] =
Network[F].client(SocketAddress(host"localhost", port"5555")).use { socket =>
socket.write(Chunk.array("Hello, world!".getBytes)) >>
socket.read(8192).flatMap { response =>
Console[F].println(s"Response: $response")
}
}
where
Network[F].client
felt wierd as i would notmally write
implictly[Network[F]].client
So i checked the code and it work and compile, so it must be that implicitly is not required anymore. I wonder since when ? is it going to be deprecated ? Can someone share the link to the scala release notes or something that state that ?
It's just a convention followed by many libraries: if FooBar[K]
is some typeclass, then one usually defines an apply
method on the companion object, with a signature that looks somewhat like this:
object FooBar {
def apply[K](implicit ev: FooBar[K]): FooBar[K] = ev
}
or maybe (if one wants to have a more precise type, in particular if one wants to have access to type members of ev
), like this:
object FooBar {
def apply[K](implicit ev: FooBar[K]): ev.type = ev
}
thereby allowing to write down value-level expressions that look exactly like the type of the expression:
FooBar[K]: FooBar[K] // desugars into FooBar.apply[F](<implicit instance>)
Here is this method in Network
(link to github, comments are mine):
def apply[F[_]](implicit F: Network[F]): F.type = F
// ^--- type-constructor
// ^--- value
// ^--- type-constructor
// ^--- value
// ^--- value
This convention is independent of and mostly unaffected by the implicitly
/summon
change in Scala 3.
implicitly
isn't deprecated.
There is a pattern, generally seen in the typelevel ecosystem, of which fs2 is one, of having the apply
method in the companion object be a synonym for implicitly
, which allows user code to not use implicitly
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With