Я думал, что в принципе система типа haskell запретит вызывать нечистые функции (т.е. f :: a -> IO b
) из чистых, но сегодня я понял, что, называя их с помощью return
, они компилируются просто отлично. В примере:
h :: Maybe ()
h = do
return $ putStrLn "???"
return ()
Теперь h
работает в возможно монаде, но это чистая функция. Компиляция и запуск этого метода просто возвращает Just ()
, как и следовало ожидать, без ввода каких-либо операций ввода-вывода. Я думаю, что haskell лень объединяет вещи (т.е. putStrLn
возвращаемое значение не используется - и не может, поскольку его конструкторы значений скрыты, и я не могу сопоставить их с ним), но почему этот код является законным? Существуют ли другие причины, позволяющие это разрешить?
В качестве бонуса, связанный с ним вопрос: вообще, можно ли вообще запретить исполнение действий монады изнутри других? Как?