在Mark Seemann的博客文章和示例中,我初步了解到自由单子作为一种组织纯代码和IO代码之间边界的方式。我的基本理解是,自由单子允许您构建一个程序(抽象语法树-AST)的纯函数,然后解释器将其转换为一系列不纯的过程调用。因此,这个解释器将AST的纯操作转换为一系列单子IO操作。
我想知道这是否重复了Haskell运行时已经使用IO单子所做的事情。如果我将IO视为没有什么特别之处,而是一种常规的单子,其绑定函数
因此,在这种观点下,返回IO操作的函数只是构建了AST,然后由Haskell运行时解释。但到目前为止,一切都是纯的。在这种观点下,函数
这个直觉正确吗?如果不是,它的局限性在哪里?
我想知道这是否重复了Haskell运行时已经使用IO单子所做的事情。如果我将IO视为没有什么特别之处,而是一种常规的单子,其绑定函数
>>=
通过IO中的所有单子操作顺序地传递“Real World”的状态,那么这种排序本身并不提供任何计算(如在这里的优秀答案中对自由单子所解释的)。然后,我可以将所有IO操作(如getLine
、writeFile
等)视为自由IO单子中的操作,将Haskell运行时视为解释器。运行时通过某些底层系统调用、C FFI调用或类似方法解释每个IO操作,这显然是不纯的。因此,在这种观点下,返回IO操作的函数只是构建了AST,然后由Haskell运行时解释。但到目前为止,一切都是纯的。在这种观点下,函数
a -> IO b
并不是不纯的,就像自由单子中的操作一样不纯。这个直觉正确吗?如果不是,它的局限性在哪里?
IO
和自由单子都是正确的。 - Fyodor Soikin