在纯函数式编程中使用 IO 的 monad 的替代方案是什么?

发布于 2024-08-19 16:40:17 字数 65 浏览 5 评论 0原文

monad 被描述为处理 IO 的 haskell 解决方案。我想知道是否还有其他方法可以用纯函数式语言处理 IO。

monads are described as the haskell solution to deal with IO. I was wondering if there were other ways to deal with IO in pure functional language.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

我ぃ本無心為│何有愛 2024-08-26 16:40:17

纯函数式语言中 I/O 的 monad 有哪些替代方案?

我知道文献中有两种替代方案:

  • 一种是所谓的线性类型系统。这个想法是,线性类型的值必须恰好使用一次:您不能忽略它,也不能使用它两次。考虑到这个想法,您可以为世界状态提供一个抽象类型(例如,World),并使其成为线性的。如果我用星号标记线性类型,那么以下是一些 I/O 操作的类型:

    getChar::World* -> (查尔、世界*)
    putChar :: 字符 ->世界* ->世界*
    

    等等。编译器会安排确保您永远不会复制世界,然后它可以安排编译就地更新世界的代码,这是安全的,因为只有一个副本。

    语言中输入的唯一性Clean基于线性。

    该系统有几个优点;特别是,它不会像 monad 那样对事件强制执行总排序。它还倾向于避免您在 Haskell 中看到的“IO sin bin”,其中所有有效计算都被扔进 IO monad 中,并且它们都得到无论您是否想要全序,它都是全序的。

  • 我知道的另一个系统早于 monads 和 Clean,它基于这样的思想:交互式程序是从请求序列(可能是无限的)到请求序列(可能是无限的)的函数。 响应序列。这个系统被称为“对话框”,对于编程来说简直就是地狱。没有人会错过它,也没有什么特别值得推荐的。 介绍 Monadic I/O 的论文很好地列举了它的缺点( 命令式函数式编程,作者:Wadler 和 Peyton Jones。本文还提到了一个基于延续的 I/O 系统,该系统由耶鲁 Haskell 小组引入,但寿命很短。

What alternatives are there to monads for I/O in a pure functional language?

I'm aware of two alternatives in the literature:

  • One is a so-called linear type system. The idea is that a value of linear type must be used exactly one time: you can't ignore it, and you can't use it twice. With this idea in mind, you give the state of the world an abstract type (e.g., World), and you make it linear. If I mark linear types with a star, then here are the types of some I/O operations:

    getChar :: World* -> (Char, World*)
    putChar :: Char -> World* -> World*
    

    and so on. The compiler arranges to make sure you never copy the world, and then it can arrange to compile code that updates the world in place, which is safe because there is only one copy.

    The uniqueness typing in the language Clean is based on linearity.

    This system has a couple of advantages; in particular, it doesn't enforce the total ordering on events that monads do. It also tends to avoid the "IO sin bin" you see in Haskell where all effectful computations are tossed into the IO monad and they all get totally ordered whether you want total order or not.

  • The other system I'm aware of predates monads and Clean and is based on the idea that an interactive program is a function from a (possibly infinite) sequence of requests to a (possibly infinite) sequence of responses. This system, which was called "dialogs", was pure hell to program. Nobody misses it, and it had nothing in particular to recommend it. Its faults are enumerated nicely in the paper that introduced monadic I/O (Imperative Functional Programming) by Wadler and Peyton Jones. This paper also mentions an I/O system based on continuations which was introduced by the Yale Haskell group but which was short-lived.

久光 2024-08-26 16:40:17

除了线性类型之外,还有效果系统

Besides linear types, there's also effect system.

书信已泛黄 2024-08-26 16:40:17

如果“纯粹”的意思是“引用透明”,即应用的函数可以与其计算结果自由互换(因此使用相同参数调用函数每次都会得到相同的结果),任何有状态 IO 的概念根据定义几乎被排除在外。

我知道有两种粗略的策略:

  • 让一个函数执行 IO,但确保永远不会使用完全相同的参数调用它两次;这通过让函数变得简单地“引用透明”来回避这个问题。

  • 将整个程序视为单个纯函数,以“收到的所有输入”作为参数并返回“产生的所有输出”,两者都由某种形式的惰性流表示以允许交互。

有多种方法可以实现这两种方法,以及一定程度的重叠——例如,在第二种情况下,在 I/O 流上操作的函数不太可能被流的同一部分调用两次。哪种看待它的方式更有意义取决于该语言为您提供了什么样的支持。

在 Haskell 中,IO 是一种 monad,它自动通过代码将顺序状态线程化(类似于功能上纯的 State monad),这样,从概念上讲,每次调用否则,不纯函数会获得隐式“外部世界状态”的不同值。

我知道的另一种流行方法使用类似 线性类型 来达到类似的目的;通过具有无法复制或重复的值来确保不纯函数永远不会两次获得相同的参数,以便“外部世界状态”的旧值无法保留和重用。

If by "pure" you mean "referentially transparent", that is, that an applied function is freely interchangeable with its evaluated result (and therefore that calling a function with the same arguments has the same result every time), any concept of stateful IO is pretty much excluded by definition.

There are two rough strategies that I'm aware of:

  • Let a function do IO, but make sure that it can never be called twice with the exact same arguments; this side-steps the issue by letting the functions be trivially "referentially transparent".

  • Treat the entire program as a single pure function taking "all input received" as an argument and returning "all output produced", with both represented by some form of lazy stream to allow interactivity.

There are a variety of ways to implement both approaches, as well as some degree of overlap--e.g., in the second case, functions operating on the I/O streams are unlikely to be called twice with the same part of the stream. Which way of looking at it makes more sense depends on what kind of support the language gives you.

In Haskell, IO is a type of monad that automatically threads sequential state through the code (similar to the functionally pure State monad), such that, conceptually, each call to an otherwise impure function gets a different value of the implicit "state of the outside world".

The other popular approach I'm aware of uses something like linear types to a similar end; insuring that impure functions never get the same arguments twice by having values that can't be copied or duplicated, so that old values of the "state of the outside world" can't be kept around and reused.

夏の忆 2024-08-26 16:40:17

Clean 中使用唯一性类型

Uniqueness typing is used in Clean

满身野味 2024-08-26 16:40:17

Peyton Jones 和 Wadler 的命令式函数式编程是如果您对函数式 IO 感兴趣,请务必阅读。他们讨论的其他方法是:

  • 对话是响应和请求的惰性流

type Dialogue = [Response] -> [Request]

main :: Dialogue

  • Continuations - 每个 IO 操作都采用延续作为参数

  • 线性类型- 类型系统以无法复制或破坏外部状态的方式限制您,这意味着您不能以相同的状态调用函数两次。

Imperative Functional Programming by Peyton Jones and Wadler is a must read if you are interested in functional IO. The other approaches that they discuss are:

  • Dialogues which are lazy streams of responses and requests

type Dialogue = [Response] -> [Request]

main :: Dialogue

  • Continuations - each IO operation takes a continuation as argument

  • Linear types - the type system restricts you in a way that you cannot copy or destroy the outside state, which means that you can't call a function twice with the same state.

鱼忆七猫命九 2024-08-26 16:40:17

函数响应式编程是处理这个问题的另一种方法。

Functional Reactive Programming is another way to handle this.

荒芜了季节 2024-08-26 16:40:17

我想知道是否还有其他方法可以用纯函数式语言处理 IO。

只需添加此处已有的其他答案:

  • 本文 的标题说明了一切: -)
  • 您还可以看看:

Rebelsky SA (1992) I/O 树和交互式惰性函数式编程。见:Bruynooghe M.、Wirsing M.(编)编程语言实现和逻辑编程。 PLILP 1992。计算机科学讲义,第 631 卷。施普林格,柏林,海德堡

  • 当 Haskell 还年轻时,Lennart Augustsson 写过使用系统令牌作为 I/O 机制:

L.奥古斯特松。使用系统令牌的功能 I/O。 PMG 备忘录 72,查尔姆斯理工大学计算机科学系,S-412 96 哥德堡,1989 年。

我还没有找到在线副本,但我并不迫切需要它,否则我建议联系查尔姆斯理工大学的图书馆。

I was wondering if there were other ways to deal with IO in a pure functional language.

Just adding to the other answers already here:

  • The title of this paper says it all :-)
  • You could also look at:

Rebelsky S.A. (1992) I/O trees and interactive lazy functional programming. In: Bruynooghe M., Wirsing M. (eds) Programming Language Implementation and Logic Programming. PLILP 1992. Lecture Notes in Computer Science, vol 631. Springer, Berlin, Heidelberg

  • When Haskell was young, Lennart Augustsson wrote of using system tokens as the mechanism for I/O:

L. Augustsson. Functional I/O Using System Tokens. PMG Memo 72, Dept Computer Science, Chalmers University of Technology, S-412 96 Göteborg, 1989.

I've yet to find a online copy but I have no pressing need for it, otherwise I suggest contacting the library at Chalmers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文