monad被描述为处理IO的haskell解决方案。我想知道是否有其他方法可以用纯函数式语言处理IO。
答案 0 :(得分:35)
纯函数式语言中I / O的monad有哪些替代方法?
我知道文献中有两种选择:
一个是所谓的线性类型系统。这个想法是线性类型的值必须完全一次使用:你不能忽略它,你不能使用它两次。考虑到这个想法,你给世界的状态一个抽象类型(例如,World
),并使它成为线性的。如果我用星号标记线性类型,那么这里是一些I / O操作的类型:
getChar :: World* -> (Char, World*)
putChar :: Char -> World* -> World*
等等。编译器安排确保你永远不会复制世界,然后它可以安排编译更新世界的代码,这是安全的,因为只有一个副本。
使用Clean语言输入的唯一性基于线性。
该系统有几个优点;特别是,它不会强制monad所做事件的总排序。它也倾向于避免你在Haskell中看到的“IO
sin bin”,其中所有有效计算被扔进IO
monad并且无论你想要总数,它们都会被完全排序订购与否。
我所知道的另一个系统早于monad和Clean,并且基于这样的想法:交互式程序是一个函数,从(可能是无限的)请求序列到(可能无限的响应序列。这个被称为“对话”的系统纯粹是编程的地狱。没有人会错过它,并没有特别推荐它。 Wadler和Peyton Jones在the paper that introduced monadic I/O (Imperative Functional Programming)中很好地列举了它的错误。本文还提到了一个基于延续的I / O系统,该系统由耶鲁Haskell小组引入,但是很短暂。
答案 1 :(得分:8)
除线性类型外,还有effect system。
答案 2 :(得分:5)
如果“纯粹”是指“引用透明”,也就是说,应用函数可以与其评估结果自由互换(因此,每次调用具有相同参数的函数都具有相同的结果),任何概念状态IO的定义几乎被排除在外。
我知道有两个粗略的策略:
让一个函数执行IO,但要确保它永远不能使用完全相同的参数调用两次;这方面通过让功能简单地“引用透明”来解决问题。
将整个程序视为一个单独的纯函数,将“收到的所有输入”作为参数并返回“所有输出产生”,两者都由某种形式的惰性流表示,以允许交互。
< / LI>有多种方法可以实现这两种方法,以及一定程度的重叠 - 例如,在第二种情况下,在I / O流上运行的函数不太可能被调用两次与相同的部分流。以何种方式查看它更有意义取决于语言给予您的支持。
在Haskell中,IO
是一种monad类型,它通过代码自动对顺序状态进行线程化(类似于功能上纯State
monad),这样,从概念上讲,每次调用其他不纯的函数获得隐含的“外部世界状态”的不同值。
我所知道的另一种流行的方法是使用类似linear types的类似结果;通过具有无法复制或复制的值,确保不纯函数永远不会获得相同的参数两次,以便“外部世界状态”的旧值不能保留并重复使用。
答案 3 :(得分:5)
Imperative Functional Programming。他们讨论的其他方法是:
type Dialogue = [Response] -> [Request]
main :: Dialogue
Continuations - 每个IO操作都将继续作为参数
线性类型 - 类型系统以不能复制或破坏外部状态的方式限制您,这意味着您无法以相同的状态调用函数两次。
答案 4 :(得分:4)
答案 5 :(得分:3)
Functional Reactive Programming是解决此问题的另一种方式。
答案 6 :(得分:1)
我想知道是否还有其他方法可以用纯函数式语言处理IO。
只需在此处添加其他答案即可:
Rebelsky S.A.(1992)I / O树和交互式惰性函数编程。在:Bruynooghe M.,Wirsing M.(eds)编程语言实现和逻辑编程中。 PLILP1992。计算机科学讲义,第631卷。施普林格,柏林,海德堡
L。奥古斯特森。使用系统令牌的功能性I / O。查尔默斯理工大学计算机科学系PMG Memo 72,S-412 96,哥德堡,1989年。
我还没有找到在线副本,但是我迫切需要它,否则,我建议联系查默斯图书馆。