Scala PartialFunctions от конкретных - PullRequest
5 голосов
/ 26 июля 2011

Есть ли какой-нибудь быстрый способ использовать в качестве конкретной функции (типа, скажем, (A) => B) как PartialFunction[A, B]? Самый краткий синтаксис, который я знаю:

(a: A) => a match { case obj => func(obj) }

Есть ли где-нибудь неявное преобразование, что-то вроде:

implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] {

  def isDefinedAt(a: A) = true
  def apply(a: A) = func(a)

}

Наверное, я только что написал то, что искал, но существует ли это уже в библиотеках Scala?

Ответы [ 2 ]

5 голосов
/ 27 июля 2011

Делать это с неявным преобразованием опасно по той же причине, по которой (A) => B не должен наследоваться от PartialFunction[A, B].Таким образом, контракт PartialFunction гарантирует, что вы можете безопасно * позвонить apply, куда бы isDefinedAt не вернул true.Контракт Function1 не предоставляет такой гарантии.

Ваше неявное преобразование приведет к PartialFunction, которая нарушает его контракт, если вы примените его к функции, которая не определена повсеместно.Вместо этого используйте сутенера, чтобы сделать преобразование явным:

implicit def funcAsPartial[A, B](f: A => B) = new {
   /** only use if `f` is defined everywhere */
   def asPartial(): PartialFunction[A, B] = {
      case a => f(a)
   }

   def asPartial(isDefinedAt: A => Boolean): PartialFunction[A, B] = {
      case a if isDefinedAt(a) => f(a)
   }
}

// now you can write
val f = (i: Int) => i * i

val p = f.asPartial // defined on all integers
val p2 = f.asPartial(_ > 0) // defined only on positive integers

* Как обсуждалось в комментариях, может быть не совсем понятно, что означает здесь «безопасность».Я думаю об этом, что PartialFunction явно объявляет свою область в следующем точном смысле: если isDefinedAt возвращает значение true для значения x, тогда apply(x) может быть оценено способом, который согласуется с намерениемавтор функции.То, что не означает, что apply(x) не будет вызывать исключение, а лишь означает, что исключение было частью конструкции функции (и должно быть задокументировано).

0 голосов
/ 26 июля 2011

Нет, я пытался найти один несколько месяцев назад и в итоге написал свой, который по сути такой же, как ваш.

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