Functional programming 是否有任何语言可以处理函数杂质(副作用),而不将其建模为现实世界或IO?

Functional programming 是否有任何语言可以处理函数杂质(副作用),而不将其建模为现实世界或IO?,functional-programming,side-effects,io-monad,Functional Programming,Side Effects,Io Monad,在Haskell(以及其他函数式语言)中,有一件事一直困扰着我,那就是整个语言都是纯的,但是使用一个表示整个“真实世界”的对象(例如IO monad)间接地允许产生副作用 我想知道,有没有语言可以在不建模整个世界的情况下处理这个问题?例如,将网络输入表示为一个字节数组,该数组在读取网络输入时缓慢填充。Haskell本身被指定使用类似于您在发明IO(monad)之前描述的名称Dialogs下的内容。以下示例摘自Peyton Jones和Wadler于1993年发表的(关于IO)的开创性论文: 类型

在Haskell(以及其他函数式语言)中,有一件事一直困扰着我,那就是整个语言都是纯的,但是使用一个表示整个“真实世界”的对象(例如IO monad)间接地允许产生副作用


我想知道,有没有语言可以在不建模整个世界的情况下处理这个问题?例如,将网络输入表示为一个字节数组,该数组在读取网络输入时缓慢填充。

Haskell本身被指定使用类似于您在发明
IO
(monad)之前描述的名称Dialogs下的内容。以下示例摘自Peyton Jones和Wadler于1993年发表的(关于
IO
)的开创性论文:

类型对话=[Response]->[Request]
主要内容:对话
数据请求=Putc Char | Getc
数据响应=正常|正常字符
对话
echo resps=Getc:
如果(a==eof)
然后[]
其他Putc a:
回声(下降2次)
哪里
OKCh a=响应!!1.
前面是解释:

为Haskell语言指定的I/O系统(Hudak等人[1992]) 基于对话,也称为惰性流(DelayStreams[1989]; O'Donnell[1985];Thompson[1989])。在Haskell中 程序具有类型
对话
,是列表之间函数的同义词 对I/O请求列表的I/O响应的列表

并得出了一些困难的结论:

  • 很容易提取响应中的错误元素,即同步错误
  • 响应
    数据类型必须包含针对每个请求的每个可能响应的构造函数,并且
  • 更严重的是,这种风格是不可组合的

    • 我从来没有真正喜欢过现实世界的类比。我认为它很流行,因为大多数人第一次接触到参数多态性是容器,所以他们的大脑想知道
      IO
      “包含了什么。”实际上,它包含了一种经过延迟评估的语法树数据结构,后来被解释为产生它所描述的副作用,但是,除了通过更抽象的
      IO
      类型之外,该数据结构不会向用户公开

      无论如何,除了@phipsgabler对Haskell以前使用的东西给出了极好的回答外,现在人们想要纯FP的地方几乎都使用了某种
      IO
      类型。然而,它是一种低级的、程序抽象的边缘。许多抽象都建立在它之上

      一个例子是函数式反应式编程,它有几种变体,但基本上随着时间的推移建立事件流。Elm有一个命令/订阅模型

      此外,库通常建立对其领域有意义的抽象,比如web服务通常被建模为一个函数,该函数通过
      请求
      对象调用,并返回
      响应
      对象的
      IO
      。在该函数的下一层,在不需要副作用的地方,您的界面只是纯类型的,就像一个接受
      User
      对象并为该用户的配置文件返回HTML的函数


      但在某种程度上,无论你称之为
      IO
      命令
      可观察
      ,它都归结为一个非常强大的想法,即将你想要的副作用的说明与这些效应的实际执行分离开来。形式可能不同,但基本概念不会很快消失。

      有趣的是,
      IO
      因此与我一样古老。因此,不,我不能从那里的历史经验中说:)