事実として、IO モナドを独立して実装できないことは知っていますが、正確な理由はわかりません。このコードは、関数型言語を使用して命令型パラダイムを実装しようとする試みです。この例と実際の IO の違いを説明できますか? 関数 main は正しいアクション順序を実装しているように見えますが、怠惰なままです。
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