case class Person(id: Long, name: String, organizationId: Long)
object Person {
def groupByOrg: Map[Long, Seq[Person]] = ...
}
- wrap/unwrapが存在しない
- Boxing/Unboxingが発生しない
- 大抵のDBライブラリやJSONライブラリなどでそのまま扱える
- 定義が楽
- 型安全でない
- シグネチャだけで意味が取れない
package object models {
type PersonId = Long
type PersonName = String
type OrganizationId = Long
}
case class Person(id: PersonId, name: PersonName, organizationId: OrganizationId)
object Person {
def groupByOrg: Map[OrganizationId, Seq[Person]] = ...
}
- wrap/unwrapが存在しない
- Boxing/Unboxingが発生しない
- 大抵のDBライブラリやJSONライブラリなどでそのまま扱える
- シグネチャだけで意味がわかりやすい
- 型安全でない
- 定義が手間
case class PersonId(value: Long) extends AnyVal
case class PersonName(value: String) extends AnyVal
case class OrganizationId(value: Long) extends AnyVal
case class Person(id: PersonId, name: PersonName, organizationId: OrganizationId)
object Person {
def groupByOrg: Map[OrganizationId, Seq[Person]] = ...
}
- 型安全
- シグネチャだけで意味がわかりやすい
- 特定のケースを除いてwrap/unwrap時にオーバーヘッドが存在しない
- Boxing/Unboxingが発生しない
- メソッドが定義しやすい
- 定義が手間
- DBライブラリやJSONライブラリなどで変換ロジックを書く必要がある
- 特定のケースでオーバーヘッドが存在する
import scalaz._
import scalaz.Tag._
package object models {
type Id = Long
type Name = String
}
case class Person(id: Id @@ Person, name: Name @@ Person, organizationId: Id @@ Organization)
object Person {
def groupByOrg: Map[Id @@ Organization, Seq[Person]] = ...
val tagOf: TagOf[Person] = Tag.of[Person]
}
- 型安全
- シグネチャだけで意味がわかりやすい
- wrap/unwrap時にオーバーヘッドが存在しない
- 定義が楽
- DBライブラリやJSONライブラリなどで変換ロジックを書く必要がある
- Boxing/Unboxingが発生する
メリット | デメリット | |
---|---|---|
primitive 型 | * wrap/unwrapが存在しない * Boxing/Unboxingが発生しない * 大抵のDBライブラリやJSONライブラリなどでそのまま扱える * 定義が楽 |
* 型安全でない * シグネチャだけで意味が取れない |
type alias | * wrap/unwrapが存在しない * Boxing/Unboxingが発生しない * 大抵のDBライブラリやJSONライブラリなどでそのまま扱える * シグネチャだけで意味がわかりやすい |
* 型安全でない * 定義が手間 |
値クラス | * 型安全 * シグネチャだけで意味がわかりやすい * 特定のケースを除いてwrap/unwrap時にオーバーヘッドが存在しない * Boxing/Unboxingが発生しない * メソッドが定義しやすい |
* 定義が手間 * DBライブラリやJSONライブラリなどで変換ロジックを書く必要がある * 特定のケースでオーバーヘッドが存在する |
TaggedType | * 型安全 * シグネチャだけで意味がわかりやすい * wrap/unwrap時にオーバーヘッドが存在しない * 定義が楽 |
* DBライブラリやJSONライブラリなどで変換ロジックを書く必要がある * Boxing/Unboxingが発生する |
Shapeless の newtype を使ってみた?
https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/newtype.scala