f()
и g()
должны вычислять одно и то же значение при одинаковом входном сигнале.
В чистом FP функция без аргументов должна обязательно вычислять один и тот же результат каждыйраз это называется.Так что это не чистый FP, если ваш couldThrowException
иногда возвращает \/-(true)
, а иногда -\/(NullPointerException)
.
Имеет смысл возвращать Either, если couldThrowException
принимает параметр.Если это чистая функция, она будет иметь ссылочную прозрачность, поэтому некоторые входные данные всегда будут приводить к \/-(true)
, а некоторые входные данные всегда будут приводить к -\/(NullPointerException)
.
В Scala вы вполне можете использовать функцию, которая не чистый, а не референтный прозрачный.Возможно, это класс Java.Возможно, он использует не чистую часть Scala.
Но я думаю, вы заинтересованы в соединении между миром чистого FP и нечистыми библиотеками.Классическим примером этого является IO.println
может произойти сбой по разным причинам - разрешения, файловая система переполнена и т. Д.
Классический способ справиться с этим в FP - это использовать функцию ввода-вывода, которая принимает состояние "world" в качестве входного параметра,и возвращает как результат вызова IO, так и новое «мировое» состояние.Состояние может быть «поддельным» значением, подкрепленным библиотечным кодом на нечистом языке, но это означает, что каждый раз, когда вы вызываете функцию, вы передаете другое состояние, поэтому оно прозрачно для ссылок.
Часто монада используется для инкапсуляции «мира».
Вы можете многое узнать об этом подходе, прочитав о монаде Haskell IO.
Core Scala IO не совсем чист,так что println
может выдавать и исключение, и, следовательно, как вы заметили, не полностью прозрачно по ссылкам. Scalaz предоставляет монаду ввода-вывода, похожую на монаду Haskell.
Одна вещь, на которую следует обратить внимание, потому что это сбивает с толку многих новичков: нет ничего о подходе "World", который требует монады, и IOне легко взглянуть на монаду, когда впервые узнаешь, что такое монада и почему она полезна.