Как смоделировать точку? - PullRequest
1 голос
/ 10 марта 2020

Я пытаюсь смоделировать точку с координатами x и y. Я хотел бы сделать это так, чтобы было невозможно смешать значения x и y.

Итак, я придумал следующее:

package com.craigtreptow.scrayz

package object types {
  type X = Double
  type Y = Double
  type Point = (X,Y)
}

Я тогда использовал это так:

package com.craigtreptow.scrayz.types

object Main extends App {
  val x: X = 1.1
  val y: Y = 2.2

  val p: Point = (x, x)

  println(p)
}

Я ожидал, что выдаст ошибку, но это сработало:

~/c/scrayz(master|✚2…)> sbt run                      
[info] Loading project definition from /Users/Ctreptow/code/scrayz/project
[info] Loading settings for project scrayz from build.sbt ...
[info] Set current project to Scrayz (in build file:/Users/Ctreptow/code/scrayz/)
[info] running com.craigtreptow.scrayz.types.Main 
(1.1,1.1)
[success] Total time: 1 s, completed Mar 9, 2020 6:08:49 PM

Возможно ли смоделировать Point таким образом, чтобы приведенный выше код приведет к ошибке компилятора?

1 Ответ

3 голосов
/ 10 марта 2020

Обратите внимание, что с учетом

type X = Double
type Y = Double

мы имеем X = Y, то есть они эквивалентны типов. Возможно, оберните каждую координату в свой собственный тип

final case class X(v: Double) extends AnyVal
object X {
  implicit def doubleToX(x: Double): X = X(x)
}
final case class Y(v: Double) extends AnyVal
object Y {
  implicit def doubleToY(y: Double): Y = Y(y)
}
final case class Point(x: X, y: Y)

val x: X = 1.1
val y: Y = 2.2

val p: Point = Point(x, x) // Error: type mismatch; found: X required: Y

Обратите внимание, как case class X(v: Double) оборачивает двойное число в специализированный семанти c контекст, где мы знаем, что двойное значение означает координату оси X, как в отличие от общего чистого двойника, который может принимать любое количество значений. Аналогичные рассуждения верны для моделирующей точки как класса наблюдений, в отличие от чистого кортежа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...