Add contramap and map ops to the Transformer and PartialTransformer#591
Add contramap and map ops to the Transformer and PartialTransformer#591danicheg wants to merge 11 commits intoscalalandio:2.0.0-developmentfrom
contramap and map ops to the Transformer and PartialTransformer#591Conversation
MateuszKubuszok
left a comment
There was a problem hiding this comment.
Hello, thanks for another PR!
I think we need a parity of features where possible, so both Transformer and PartialTransformer should have both map and contramap if we're adding them.
Additionally, we would prefer these operations to not live in the main typeclass but more in some dedicated trait:
// docs
trait Transformer[From, To] extends AutoDerived[From, To] {
// docs
def transform(src: From): To
}
object Transformer {
trait AutoDerived[From, To] extends TransformerOps[From, To] {
def transform(src: From): To
}
trait TransformerOps[From, To] {
def transform(src: From): To
def map[A](f: To => A): Transformer[From, A] = ...
def contramap[A](f: A => From): Transformer[A, To] = ...
}
}so that they could be called and be present in intellisense but not distract from the main use case of Transformers (and PartialTransformers) when looking in the source code.
| * | ||
| * @since 1.5.0 | ||
| */ | ||
| final def map[A](f: To => A): PartialTransformer[From, A] = new PartialTransformer[From, A] { |
There was a problem hiding this comment.
If there is map in partial, there could also be mapPartial[A](f: To => partial.Result[A]): PartialTransformer[From, A].
Since Transformer has contramap the PartialTransformer should also get one.
There was a problem hiding this comment.
I thought about this once again and don't see any issue with adding contramap to PartialTransformer and map to Transformer, respectively.
What about mapPartial, it might be useful indeed, but don't you mind if we would add it separately?
| */ | ||
| final def contramap[A](f: A => From): Transformer[A, To] = new Transformer[A, To] { | ||
| override def transform(src: A): To = self.transform(f(src)) | ||
| } |
There was a problem hiding this comment.
Since PartialTransformer has map the Transformer should also get one.
Transformer#contramap and PartialTransformer#mapcontramap and map ops to the Transformer and PartialTransformer
1ebf9a0 to
eb2ddcb
Compare
|
If you are still interested in working on this I just merged #753, which should make it more doable on 2.0.0-development branch (summoning work in expected way without an extra type per type-class, no issues with deciding which one should be extended etc). It would be released as |
Motivation
This PR adds four methods
Transformer#contramap,Transformer#map,PartialTransformer#contramapandPartialTransformer#map, to make transformers more composable and reusing existing transformers more concise and pleasant.Examples
Transformer#contramap:PartialTransformer#map:Why not use existing capabilities?
Transformer#contramapusers might doPartialTransformer#mapusers might doWell, the main reason is to be concise and to promote reusing existing transformers (at the user's site), keeping the DRY principle at its max. These combinators are also widely known in functional communities, making their usage transparent and pleasant. OTOH, there is the
chimney-catsmodule, which provides the same functionalities. However, using it would require many redundant allocations (implicit syntaxes come with their costs), which might not be ideal for GCs, especially since Chimney is often used in hot-paths of applications (based on my experience).I'd appreciate any feedback on that matter!