Является ли Option упаковкой значения хорошим шаблоном? - PullRequest
10 голосов
/ 03 февраля 2011

Я недавно написал следующий фрагмент Scala:

val f: File = ... // pretend this file came from somewhere
val foo = toFoo(io.Source.fromFile(f).mkString)

Мне действительно не понравилось, как это происходило.Чтобы понять, что происходит, вы должны начать с f в центре, читать слева до fromFile, читать справа до mkString, снова читать слева до toFoo.Тьфу.

Особенно после привыкания к функциональным преобразованиям последовательностей это трудно читать.Моя следующая попытка выглядит так:

val foo = Some(f)
  .map(io.Source.fromFile)
  .map(_.mkString)
  .map(toFoo)
  .get

Мне нравится поток этого намного лучше.Вы можете видеть, что происходит Это хорошее использование класса Option?Или я этим злоупотребляю?Есть ли лучший шаблон, который я могу использовать для достижения того же потока?

Ответы [ 3 ]

26 голосов
/ 03 февраля 2011

Это совершенно нормально.Тем не менее, есть метод |> в Scalaz , который делает его лучше, и вы можете создать его самостоятельно, если не хотите использовать весь Scalaz:

class Piper[A](a: A) { def |>[B](f: A => B) = f(a) }
implicit def pipe_everything[A](a: A) = new Piper(a)

f |> io.Source.fromFile |> {_.mkString} |> toFoo

Лично якак правило, пишут много кода, который требует скобок, и в большинстве случаев мне нравятся методы лучше, чем операторы, поэтому в моем коде я обычно называю |> «use», но это то же самое:

f.use(io.Source.fromFile).use(_.mkString).use(toFoo)

В Scala 2.11 или более поздней версии вы можете получить такое же поведение и повысить производительность с (немного) меньшим синтаксисом:

implicit class Piper[A](private val a: A) extends AnyVal {
  def |>[B](f: A => B) = f(a)
}
5 голосов
/ 04 февраля 2011

У меня нет проблем с другими ответами, приведенными здесь, но рассматривали ли вы вопрос об изменении имени toFoo на что-то, что «течет» лучше?Я имею в виду, что toFoo действительно пахнет чем-то, что должно быть в справа выражения, но если вы переименуете его во что-то другое, оно может также поместиться в left .

// toFoo, as defined by you
val foo = toFoo(io.Source.fromFile(f).mkString)
// Same function, different name
val foo = createFooFrom(io.Source.fromFile(f).mkString)
4 голосов
/ 03 февраля 2011

Вы добавляете toFoo к String через шаблон pimp my library. Тогда это становится:

val foo = Source fromFile f mkString () toFoo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...