Я знаю как факт, что мы не можем реализовать монаду IO самостоятельно, но я не знаю, почему именно. Этот код является попыткой реализации императивной парадигмы с использованием функционального языка. Можете ли вы объяснить разницу между этим примером и истинным IO? Похоже, функция main реализует правильный порядок действий и остается ленивой.Выполнение ввода-вывода внутри Haskell
import System.IO.Unsafe
data Io a = Io a
runIO :: Io a -> a
runIO (Io a) = a
instance Monad Io where
return x = Io x
Io a >>= f = f a
-- internal side effect function
output :: Show a => a -> Io()
output s = return $! unsafePerformIO $ print s
----------------------------------------------------------------
mainIO :: Io()
mainIO = do output "A"
b <- return "B"
output b
output b
x <- return (undefined :: String)
return undefined
output "C"
head [output "C", output "C"]
output x
output "D"
test = runIO mainIO
выход:
"A"
"B"
"B"
"C"
"C"
<interactive>: Prelude.undefined
Спасибо за ответ и ссылку! Im новый на этом сайте, поэтому, если я задам несколько вопросов позже в этом разделе, кто-нибудь заметит это? Или будет лучше создать новую тему? – user1374768
Кстати, мой вопрос появился после прочтения этого учебника http://www.haskell.org/haskellwiki/IO_inside и этого документа http://webcache.googleusercontent.com/search?q=cache:ry-JwgJnib0J:research. microsoft.com/pubs/67066/imperative.ps.z+hl=ru(a,RealWorld) – user1374768
Здесь используется тип IO, определенный как RealWorld -> (a, RealWorld), поэтому последовательность действий реализуется с использованием поддельного параметра Реальный мир. Но ИМХО эта модель невозможна на чистом языке без внешних взломов компилятора. Поэтому я удивляюсь, почему эта реализация используется, надеюсь, что в pdf более понятно объяснение. – user1374768