Scala - use a companion object as a shorthand argument for a block accept function

I have a set of model objects and a set of wrapper objects to provide them with additional functionality.

I would like to be able to convert collections of model objects into fairing objects in a compressed form, using the same shorthand that allows me to write List("x", "y", "z").foreach(println) , for example:

 class Model class ModelWrapper(val m: Model) object ModelWrapper { def apply(model: Model) = new ModelWrapper(model) } val m1 = new Model; val m2 = new Model; val m3 = new Model List(m1, m2, m3).map(ModelWrapper) 

So, ModelWrapper , passed as an argument, is converted to ModelWrapper(_) , a call to the companion object.

However, when I try to do this, I get a type mismatch error:

 <console>:14: error: type mismatch; found : ModelWrapper.type (with underlying type object ModelWrapper) required: Model => ? List(m1, m2, m3).map(ModelWrapper) 

However, if I make ModelWrapper a case class and delete the companion object, it works. I don’t want this to be a case class, because the behavior it adds doesn’t mix well with the general way the classes work. For example, two wrapper classes with the same model class as the parameter are not necessarily equal.

What would I like to know, what is the difference between the case class and the companion object in this case? Can I get what I want without using the case class?

+4
source share
3 answers

Your companion object should be a function:

 object ModelWrapper extends Function1[Model, ModelWrapper] { def apply(model: Model) = new ModelWrapper(model) } 

Or perhaps you prefer this abbreviation:

 object ModelWrapper extends (Model => ModelWrapper) { def apply(model: Model) = new ModelWrapper(model) } 
+10
source

For some reason, these works:

  List(m1, m2, m3).map(ModelWrapper(_)) List(m1, m2, m3).map(ModelWrapper.apply) 

It seems that for case classes, since the companion object is created by the compiler, not you, it knows that you are referencing ModelWrapper.apply . When there is a companion, he thinks that you mean the satellite.

+4
source

Martin Odersky answers a historical question on this duplicate question:

Why do companion class objects extend FunctionN?

This question also provides a little more context.

+1
source

Source: https://habr.com/ru/post/1401149/


All Articles