(scalaz) для необязательного вызова цепного метода - PullRequest
2 голосов
/ 08 декабря 2011

У меня есть:

val having: Option[String] = ...

val averageStream = having match {
  case Some(expr) => stream[TimeMovingAverage].filter("name = '#name'").where(expr)
  case None       => stream[TimeMovingAverage].filter("name = '#name'")
}

Есть ли какая-нибудь магия скаляза, которая устранит дублирование?

Я мог бы сделать что-то вроде

val averageStream1 = stream[TimeMovingAverage].filter("name = '#name'")
val averageStream2 = having.map(averageStream1.where(_))

Но это кажетсянемного неловкоЯ думаю, что я ищу что-то вроде

val averageStream = stream[TimeMovingAverage].filter("name = '#name'") |?| having.cata(_.where(_), _)
// Clearly some ambiguities with the _'s here

1 Ответ

2 голосов
/ 08 декабря 2011
stream[TimeMovingAverage].filter("name = '#name'") |> { str =>
  having.cata(str.where(_), str)
}

или даже

stream[TimeMovingAverage].filter("name = '#name'") |> (
  having.cata(expr => _.where(expr), identity) : T => T
)

T => T необходимо изменить на тип stream[TimeMovingAverage], что делает его менее практичным, если вы не найдете следующую специализацию |> в scalaz или не определите ее самостоятельно:

implicit def WrapIt[T](t: T) = new {
  def |~> (arg: T => T) = arg(t)
  def |?> (arg: Option[T => T]): T = arg.getOrElse(identity (_:T)).apply(t)
}

stream[TimeMovingAverage].filter("name = '#name'") |~> having.cata(expr => _.where(expr), identity)

stream[TimeMovingAverage].filter("name = '#name'") |?> having.map(expr => _.where(expr))

Не уверен, стоит ли действительно что-то подобное делать.

...