Побочные эффекты в Scala

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

скобках замечание для тех, кто не знаком с Haskell

одна черта, которая мне нравится в Haskell, заключается в том, что не только функции являются первоклассными гражданами, но и побочные эффекты (позвольте мне назвать их действиями). Действие, которое при выполнении наделит вас значением типа a, принадлежит к определенному типу IO a. Вы можете передавать эти действия, как и любую другую ценность, и комбинировать их интересными способами.

В самом деле объединение побочные эффекты-единственный способ в Haskell сделать что-то с ними, так как вы не можете их выполнить. Скорее, программа, которая будет быть выполнено, является комбинированным действием, которое возвращается вашим

2 ответов


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

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


возможность обеспечения ссылочной прозрачности это в значительной степени несовместимо с целью Scala иметь систему классов/объектов, которая совместима с Java.

Java-код может быть нечистым произвольным образом (и может быть недоступен для анализа при запуске компилятора Scala), поэтому компилятор Scala должен был бы предположить все внешний код нечист (присвоение им IO type). Чтобы реализовать чистый код Scala с вызовами Java, вам придется обернуть вызовы в чем-то эквивалентном unsafePerformIO. Это добавляет шаблонность и делает взаимодействие намного менее приятным, но становится хуже.

предполагая, что весь код Java находится в IO Если программист не обещает иначе, в значительной степени убьет наследование от классов Java. Все унаследованные методы должны были бы предполагаться в IO type; это было бы даже верно для интерфейсов, так как компилятор Scala должен был бы предположить существование нечистого реализация где-то там, в Java-land. Таким образом, вы никогда не могли бы получить класс Scala с любым не-IO методы из Java-класса или интерфейса.

еще хуже, даже для классов, определенных в Scala, теоретически может быть неотслеживаемый подкласс, определенный в Java с нечистыми методами, экземпляры которого могут быть переданы обратно в Scala как экземпляры родительского класса. Поэтому, если компилятор Scala не может доказать что данный объект не может быть экземпляром из класса, определенного Java-кодом, он должен предположить, что любой вызов метода для этого объекта может вызвать код, который был скомпилирован компилятором Java без соблюдения законов того, какие функции возвращают результаты не в IO можно сделать. Это заставило бы почти все о IO. Но положить все в IO точно эквивалентно ничего не помещать в IO и просто не отслеживать побочные эффекты!

Итак, в конечном счете, Scala рекомендует вам напишите чистый код, но он не пытается заставить вас сделать это. Что касается компилятора, любой вызов чего-либо может иметь побочные эффекты.