Есть ли в Scala уже существующая библиотечная функция для преобразования исключений в Options? - PullRequest
20 голосов
/ 04 ноября 2011

Это в основном для обертывания фабричных методов java, которые выдают исключения, если элемент не может быть создан на основе входных данных. Я ищу что-то в базовой библиотеке, например:

 def exceptionToOption[A](f: => A):Option[A] ={
    try{
      Some(f)}
    catch{
      case e:Exception => None}
  }

Использование:

val id:Option[UUID] = exceptionToOption(UUID.fromString("this will produce None"))

Я знаю, что могу написать свое, но хочу убедиться, что я не изобретаю колесо заново.

Ответы [ 5 ]

16 голосов
/ 04 ноября 2011

Использование scala.util.control.Exception :

import scala.util.control.Exception._

allCatch opt f

И вы можете сделать это более изощренным. Например, чтобы перехватывать только арифметические исключения и извлекать исключение:

scala> catching(classOf[ArithmeticException]) either (2 / 0)
res5: Either[Throwable,Int] = Left(java.lang.ArithmeticException: / by zero)
11 голосов
/ 04 ноября 2011

Да, вы можете взглянуть на объект scala.util.control.Exception. Особенно функция allCatch.

10 голосов
/ 16 июня 2014

Начиная с scala 2.10, вы можете запустить свой код (например, фабричный метод) в scala.util.Try , а затем преобразовать его в toOption:

import scala.util.Try
Try("foo".toInt).toOption  // None
Try("7".toInt).toOption    // Some(7)

переведено на ваш оригинальный пример:

val id: Option[UUID] = Try(UUID.fromString("this will produce None")).toOption
1 голос
/ 05 ноября 2011

Scalaz обеспечивает Проверка [+ E, + A] , которая похожа на Either.

val result: Validation[Throwable, Something] = ...

result match {
  case Success(x) => ...
  case Failure(x) => ...
}
0 голосов
/ 22 июня 2019

Я использую шаблон, основанный на сигнальных и не сигнальных NaNs в современных компьютерах.NaN означает не число.Деление на ноль (fp) создает NaN.sNaNs генерируют исключения, не сигнализирующие NaN просто предоставляются в результате, любое будущее вычисление результата также генерирует NaN.Evaluate - это сигнализация, TryEvaluate - не сигнализация.

Здесь Ctx = Context [I, R] - это блок контекста, который содержит входные данные функции [I], результат [R] и исключение.Все варианты.Метод обновления в контексте является копией-обновлением.Не мутирующее обновление.Супер-черта просто оценивает одну или несколько функций, передавая обновленный контекст следующей функции.Основная функция оценки возвращает контекст, если удерживается исключение (пропуская оценку).Контекст [I, R] имеет функцию, которая переводит (I => R) в (Context [I, R] => Контекст [I, R]).Таким образом, нормальная функция может быть легко преобразована в контекстную функцию.

Как видите, кода не так много.Черты находятся в моем пакете утилит и могут быть использованы практически без кода потребителем.Использование библиотеки добавляет много накладных расходов для выполняемой работы.

Я использую это для всех моих парсеров.Парсеры, основанные на X-Path, просто вызывают последовательность подпарсеров.Следовательно, метод оценки (Seq).Примечание: мне не нравятся методы.Я стараюсь использовать функции там, где могу.

Упс, я думаю, что выкладывал мусор в последний раз.Вот ссылка на GitHub.https://github.com/tyohDeveloper/acme/tree/master/src/acme/util

...