Skip to content

Commit 31b565b

Browse files
authored
Update guidelines.md (#2095)
1 parent 60d3c12 commit 31b565b

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

docs/src/main/tut/guidelines.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ The user doesn't need to specify the type `A` which is given by the parameter.
6969
You probably noticed that there is a `val dummy: Boolean` in the `PurePartiallyApplied` class. This is a trick we used
7070
to make this intermediate class a [Value Class](http://docs.scala-lang.org/overviews/core/value-classes.html) so that there is no cost of allocation, i.e. at runtime, it doesn't create an instance of `PurePartiallyApplied`. We also hide this partially applied class by making it package private and placing it inside an object.
7171

72-
### <a id="ops-classes" href="#implicit-naming"></a> Implicit naming
72+
### <a id="implicit-naming" href="#implicit-naming"></a> Implicit naming
7373

7474
In a widely-used library it's important to minimize the chance that the names of implicits will be used by others and
7575
therefore name our implicits according to the following rules:
@@ -84,5 +84,32 @@ As an example, an implicit instance of `Monoid` for `List` defined in the packag
8484

8585
This rule is relatively flexible. Use what you see appropriate. The goal is to maintain uniqueness and avoid conflicts.
8686

87+
88+
89+
### <a id="implicit-priority" href="#implicit-priority"></a> Implicit instance priority
90+
91+
When there are multiple instances provided implicitly, if the type class of them are in the same inheritance hierarchy,
92+
the instances need to be separated out into different abstract class/traits so that they don't conflict with each other. The names of these abstract classes/traits should be numbered with a priority with 0 being the highest priority. The abstract classes/trait
93+
with higher priority inherits from the ones with lower priority. The most specific (whose type class is the lowest in the hierarchy) instance should be placed in the abstract class/ trait with the highest priority. Here is an example.
94+
95+
```scala
96+
@typeclass
97+
trait Functor[F[_]]
98+
99+
@typeclass
100+
trait Monad[F[_]] extends Functor
101+
102+
...
103+
object Kleisli extends KleisliInstance0
104+
105+
abstract class KleisliInstance0 extends KleisliInstance1 {
106+
implicit def catsDataMonadForKleisli[F[_], A]: Monad[Kleisli[F, A, ?]] = ...
107+
}
108+
109+
abstract class KleisliInstance1 {
110+
implicit def catsDataFunctorForKleisli[F[_], A]: Functor[Kleisli[F, A, ?]] = ...
111+
}
112+
```
113+
87114
#### TODO:
88115
Once we drop 2.10 support, AnyVal-extending class constructor parameters can be marked as private.

0 commit comments

Comments
 (0)