Разница между созданием экземпляра класса и объекта-компаньона - PullRequest
0 голосов
/ 20 декабря 2018

Я читаю и работаю над упражнениями из книги «Функциональное программирование в Scala».В главе о тестировании свойств в одном упражнении предлагается реализовать def listOf[A](g: Gen[A]): SGen[List[A]], здесь приведен соответствующий код:

case class Gen[+A](sample: State[RNG, A]) {

  def flatMap[B](f: A ⇒ Gen[B]): Gen[B] =
    Gen(sample.flatMap(f(_) sample))

  /* A method alias for the function we wrote earlier. */
  def listOfN(size: Int): Gen[List[A]] =
    Gen.listOfN(size, this)

  def listOfN(size: Gen[Int]): Gen[List[A]] =
    size flatMap (Gen listOfN (_, this))
}

object Gen {
  def listOfN[A](n: Int, g: Gen[A]): Gen[List[A]] =
    Gen(State.sequence(List.fill(n)(g.sample)))

  def listOf[A](g: Gen[A]): SGen[List[A]] =
  //  SGen { n ⇒ g.listOfN(n) }
  //  SGen{listOfN(_, g)}
}

case class SGen[+A](forSize: Int ⇒ Gen[A])

Как видите, listOf[A](g: Gen[A]): SGen[List[A]] реализован двумя способами, второе -один я подумал, и первым является решение, предоставленное книгой.

Мой вопрос: есть ли разница между созданием этого SGen с помощью объекта-компаньона и созданием его с помощью метода listOfN в генераторе g?Я полагаю, до тех пор, пока обе реализации используют g для генерации значений, разница невелика.

1 Ответ

0 голосов
/ 20 декабря 2018

В этом примере нет практической разницы.Из реализации видно, что Gen.listOfN(size: Int) просто вызывает реализацию объекта-компаньона.Одним из преимуществ псевдонима метода является то, что вы можете использовать более простой синтаксис в объекте-компаньоне, например:

object Gen {
    ...
    def listOf[A](g: Gen[A]): SGen[List[A]] =
        SGen(g.listOfN)
}

Наличие этих различных параметров синтаксиса может оказать большее влияние на ясность, когда пользователи создают большие композиции.

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