Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - use companion object as shorthand argument to function accepting block

I have a set of model objects and a set of wrapper objects to give them extra functionality.

I'd like to be able to convert collections of model objects to wrapper objects concisely, using the same shorthand that allows you to write List("x", "y", "z").foreach(println), like this:

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 that ModelWrapper, passed as an argument, is converted to ModelWrapper(_), a call on the companion object.

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

<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 remove the companion object, it works. I don't want to make it a case class as the behaviour it's adding does not fit well with the overall way in which case classes work. Two wrapper classes with the same model class as a parameter are not necessarily equal, for example.

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

like image 291
Russell Avatar asked Dec 10 '22 01:12

Russell


1 Answers

Your companion object must be a function:

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

Or may be you'll prefer this abbreviation:

object ModelWrapper extends (Model => ModelWrapper) { def apply(model: Model) = new ModelWrapper(model) }
like image 193
Sergey Passichenko Avatar answered Mar 22 '23 22:03

Sergey Passichenko