Haskell中的IO实现

use*_*768 2 io haskell semantics

我知道,我们不能独立实现IO monad,但我不知道为什么.此代码试图使用函数式语言实现命令式范例.你能解释一下这个例子和真正的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 
Run Code Online (Sandbox Code Playgroud)

输出:

"A"
"B"
"B"
"C"
"C"
<interactive>: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)

Don*_*art 11

我不确定你要表现出什么.您IO使用现有IO的目标实现嵌入了Haskell 的编码.

关键是你使用unsafePerformIOprint- 从其他IO系统借用的原语.

考虑一下:如果您没有任何其他IO系统可以依赖,该怎么办?所以没有print或其他方式调用原始IO函数.你会如何实现IO?

因此,虽然您可以在Haskell中以多种方式实现IO抽象,但您始终必须依赖新的运行时原语函数来实际调用操作系统来执行实际的IO.这是Haskell本身无法实现的.


作为参考,请参阅博士论文"效果的功能规范",Wouter Swierstra,概述了在Haskell中编码IO和其他效果的各种方法,并将IO的规范定义为纯功能数据类型(种类)你所做的事情的扩展)

在此输入图像描述