Search code examples
scalatypeclassimplicitfs2

is "implictly" in scala now deprecated or at least not required anymore?


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 ?


Solution

  • 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.