Различия между объектом case T и классом case T () при определении ADT? - PullRequest
2 голосов
/ 09 февраля 2020

Допустим, в scala у меня есть ADT следующим образом:

sealed trait Animal

object Animal {
case class Lion(name: String)    extends Animal
case class Elephant(name:String) extends Animal
case object Tiger                extends Animal
}

Здесь предпочтительно объявить Tiger как объект case или он должен быть объявлен как пустой класс case, т.е. case class Tiger()? Есть ли у кого-то преимущество перед другими?

Ответы [ 2 ]

4 голосов
/ 09 февраля 2020

Если есть только Tiger, это должен быть объект. Если может быть несколько равных Tiger s, это должен быть класс.

val tiger = Tiger()
val tiger1 = Tiger()
tiger == tiger1 // true
tiger eq tiger1 // false
2 голосов
/ 09 февраля 2020

Мои два цента: я думаю, если вы хотите объявить пустым case class как Tiger в вашем случае - остановитесь и подумайте, потому что весьма вероятно, что вы делаете что-то не так.

Классы дел были разработаны для легкой работы со структурированными данными - но если в классе дел не объявлено никаких данных, неясно, как их следует интерпретировать с точки зрения бизнес-логики c. С другой стороны - case object четко описывает определенный тип сигнала, который не требует каких-либо дополнительных данных, потому что он одиночный.

Я бы предложил немного практический пример:

/**
* Sum type describing abstract operation over some user profile in theoretical social network
*/
sealed trait UserProfileOperation

/**
* User requests edit certain field with value in it's profile
*/
case class Edit(field: String, value: String) extends UserProfileOperation 

/**
* User requests to delete own profile - no additional data required, 
* so it is always singleton type signal
*/
case object Delete extends UserProfileOperation 

Надеюсь, это поможет!

...