Note: The keyword is applied to the whole argument list, so we use two lists two differentiate what's explicit and implicit
Works the same for constructor parameters:
Passing runtime environments like ExecutionContext, ActorSystem or FlowMaterializer into methods and function of a certain type.
For example, calling ".map" on a Future without providing an implicit ExecutionContext will fail at compile-time:
Providing configuration for DSLs
For example, overriding Scalatest's property check config...
...or changing the circe json Printer for akka-http-circe:
Automatically convert one type into another.
In newer Scala versions this is considered an advanced language feature and needs to be enabled (for good reason).
Hidden conversions like that can be frustrating to debug, so please don't use them. There are better options in most cases (e.g. extension methods and typeclasses)
Implicit classes automatically subclass a type to make new methods available.
This is especially useful for types you cannot change (primitives or library classes)
(a.k.a. Extension Methods)
When you write extension methods for "foreign" types it is a good idea to have a dedicated "syntax" import. As usual cats and circe libs are a good example:
Note: IntelliJ will usually underline code that uses implicits, and there are actions
to display "Implicit conversions" and "Implicit parameters" (search for "Implicit" using cmd+shift+A)
Typeclasses are a pattern, which is often a language feature (e. g. in Haskell, Purescript, Idris), but is possible to use in Scala thanks to normal implicits.
For example you can use circe's Encoder typeclass to convert types to json as long as they have an implicit Encoder in scope:
There is syntactic sugar for requiring a typeclass called "context bound":
If they belong to a specific type, put them in the companion object of the type:
If they belong to types you don't "own" (types from libraries) or are very generic:
Either put them in a package or object and import them...
...or put them in a mixin trait