Эффекты использовать для обертывания нечистых методов? - PullRequest
0 голосов
/ 27 мая 2018

Я пытаюсь понять, как использовать эффектные монады (cats.effect.IO или scalaz.IO не имеет значения).Представьте, что у меня есть следующий метод:

def extract(str: String): String = {
    if(str.contains("123"))
        "123"
    else
        throw new IllegalArgumentException("Boom!")
}

Поскольку этот метод нечист (исключение выдается), и мне нужно объединить его результат с другим эффективным вычислением (network-IO), рекомендуется ли просто обернуть егов IO следующим образом:

def extract(str: String): IO[String] = IO {
    if(str.contains("123"))
        "123"
    else
        throw new IllegalArgumentException("Boom!")
}

Является ли это частым случаем использования монад эффектов?

1 Ответ

0 голосов
/ 27 мая 2018

Является ли это уместным или нет, зависит от того, что вы хотите выразить.

Это не похоже на ваше первое определение def extract(str: String): String, как-то недопустимо: вы просто подметаете все исключения и побочные эффекты вковрик, так что они не видны в подписи.Если это не имеет отношения к вашему текущему проекту, и если допустимо, что программа просто аварийно завершает работу с длинной трассировкой стека брошенного исключения, то сделайте это без проблем (легко представить одноразовые одноразовые сценарии, где это будетУместно).

Если вместо этого вы объявляете def extract(str: String): IO[String] = IO { ... }, то в подписи вы по крайней мере можете увидеть, что функция extract может сделать что-то нечистое (в данном случае, исключение).Теперь возникает вопрос: кто отвечает за работу с этим исключением или , где вы хотите иметь дело с этим исключением ?Учтите это: если выдается исключение, оно появится в вашем коде в строке, где вызывается что-то вроде yourProgram.unsafeRunSync().Есть ли смысл иметь дело с этим исключением там?Может, да, а может и нет: никто не может тебе сказать.Если вы просто хотите перехватить исключение на верхнем уровне в main, зарегистрировать его и exit, тогда это уместно.

Однако, если вы хотите немедленно обработать исключение, у вас естьлучшие варианты.Например, если вы пишете метод, который запрашивает имя файла, затем пытается extract что-то из этого имени и, наконец, выполняет IO для файлов, тогда тип возвращаемого значения IO[String] может быть слишком непрозрачным.Возможно, вы захотите использовать другую монаду (Option, Either, Try и т. Д.) Для представления неудачного извлечения.Например, если вы используете Option[String] в качестве типа возвращаемого значения, вам больше не придется иметь дело с неясным исключением за тысячи миль в вашем методе main, но вместо этого вы можете иметь дело с ним немедленно и, например, запроситьнесколько раз новое имя файла.

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

...