ScalaClean
ScalaClean copied to clipboard
RULE PROPOSAL: Relax parameters to supertype
The goal here is to have a rule to relax the requirements on input method parameters, whenever the extra features of a subtype are not used, and to generalise them to the super-type.
Problem Statement
Suppose the following hold:
Annis a trait or class, that declares some public methods, andBobis another trait or class that extends fromAnn.- We have trait
Fili, which is not related by subtyping toAnnorBob, which defines a methoddef kili(edo:: Bob)that takes as input parameter a valueedoof type Bob. - Suppose that all the implementations (and overriding ones) of
kilionly uses fromedothe methods or values defined in the super-typeAnn, and nowhere does it use the extra capabilities of theBobclass.
The goal, then, is to rewrite the kili method from the Fili trait, so that the type of edo is changed to Ann instead of Bob.
trait Fili {
def kili(edo: Bob): Int
}
// <<<< Before
// >>>> After
trait Fili {
def kili(edo: Ann): Int
}
Comments
Some "proverbs" of engineering, to which this rule help, are those of programming against an interface, not an implementation; as well as the old minimum access.
Examples
One circumstance in which this often happens is in the cats library, and projects that use its type-classes (which are just traits of a higuer kind). It often happens that an implicit parameter is declared to require a Monad[F] parameter, when only the map method (from the Functor trait) is used.
Here are some examples from the same set of related libraries:
- https://github.com/http4s/http4s/pull/2565
- https://github.com/typelevel/cats/pull/2854
- https://github.com/typelevel/cats/pull/2837
Great idea
This will need some controls: An example being cats-effect Bracket vs Sync. You might be using the "lower" interface because of the additional laws, which aren't represented in code.