【问题标题】:Controlling side-effects in function控制函数中的副作用
【发布时间】:2021-03-17 21:54:06
【问题描述】:

我想大多数purely functional programming languages 都具有控制功能副作用的功能,例如 Haskell 中的 monad,但由于 TEA,Elm 不需要此类功能。此外,我听说 Nim 是一种不纯粹的函数式编程语言,但它通过有/无副作用将 funcproc 分开。

那么,我有一个问题。是否有任何按可以或不能控制功能副作用分类的编程语言列表?如果没有,你能给我一些语言的名字吗?我将搜索名称并研究它是如何工作的,但如果可能的话,我很高兴你能简单地写它。以下是我知道的可以控制副作用及其方式的语言列表:

  • 由单子
    • 哈斯克尔
    • PureScript
    • 伊德里斯
    • (查找了一些类似的语言,我想应该包括Agda和Isabelle)
  • 通过代数效应(我不太理解)
    • 甲贺
    • 效果
  • 按类型
    • 干净
  • 按语法
    • 尼姆 - procfunc

另外,如果你知道,请告诉我有关控制函数副作用的文档。

【问题讨论】:

  • StackOverflow 平台不太适合要求列表的问题。
  • 顺便说一句,为了消除一些混乱,Haskell doesn't need monads to achieve IO。大多数代数效应也是单子的。我建议你多研究一下这些,以及 Haskell 创造者关于 IO 的论文。
  • 文章是否包含论文链接?无论如何,我会仔细阅读它,谢谢!
  • Elm 不会“避免”单子。它在任何地方都使用它们,只是没有提及它们的名称,并且对它们的语言支持很糟糕

标签: functional-programming side-effects purely-functional


【解决方案1】:

不,你的分类全错了。

Haskell 不需要 IO 来引入副作用,并且可以轻松绕过它。它还具有error "Oops" 概念,不受IO a 的约束,可以在纯函数中使用。例如以下定义是完全有效的 Haskell 代码:

myDiv1 :: Float -> Float -> Float
myDiv1 x 0 = error "Division by zero"
myDiv1 x y = x / y

不仅如此,您不需要任何 monad 来处理错误。考虑一下Go,这很烦人

res1, err := somePackage.SomeOperationThatMightEndWithError()
if err == Nil {
    // do something with it
}
res2, err := somePackage.SomeAnotherDangereousOperation(res1) 
if err == Nil {
    // do something with it
}

它不是单子。但它通过对整个代码库的显式错误处理来接近纯度。

同样的思维方式可以应用于您决定在原始帖子中列出的其他类别。

【讨论】:

  • 没有IO,Haskell 程序如何产生副作用?当然,您可以使用 unsafePerformIO 绕过适当的技术,就像您可以使用 error 编写部分函数而导致程序崩溃一样,但这并没有改变 Haskell 选择控制副作用的事实是 IO monad .
  • @Bergi,首先,(几乎)任何返回IO a(即以-> IO a 箭头结尾)的函数都是。这实际上就是pure :: a -> IO a 定义所要表达的意思。其次,就运行时允许“部分函数”而言,任何执行点的堆栈缠绕异常和像unsafePerformIOIO-monad 这样的脏黑客不再是您所写的“Haskell 的选择”,而是程序员的选择。或标准库的选择。但不是运行时的选择。
  • 那么您的意思是 GHC 运行时不纯?无赖。
  • @Bergi 我说的是我的帖子和 cmets 中写的内容 :) 无论你是否喜欢 Haskell,无论你是否采用 IO,你仍然可以绕过 IO 轻松地破坏那些通过签名看起来很纯粹的函数。没有冒犯,就是这样。
  • 我不同意允许 hacks 绕过控制副作用的标准方法确实使 OP 分类无效。
猜你喜欢
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 2011-04-09
  • 2011-07-19
相关资源
最近更新 更多