Haskell 和 F# 之间的主要区别是什么?

ljs*_*ljs 135 f# haskell functional-programming language-comparisons

我在互联网上搜索了F#Haskell之间的比较,但没有找到任何真正确定的东西。主要区别是什么,为什么我要选择一个而不是另一个?

Xia*_*ian 127

Haskell 是一种“纯粹的”函数式语言,而 F# 具有命令式/OO 和函数式语言的方面。Haskell 也有惰性求值,这在函数式语言中相当罕见。

这些东西是什么意思?纯函数式语言,意味着没有副作用(或调用函数时共享状态的变化),这意味着您可以保证,如果调用 f(x),除了从函数返回值外,不会发生任何其他事情,例如控制台输出、数据库输出、对全局或静态变量的更改……尽管 Haskell 可以具有非纯函数(通过 monad),但它必须通过声明“显式”隐含。

纯函数式语言和“无副作用”编程最近很受欢迎,因为它非常适合多核并发,因为没有共享状态而不是无数的锁和信号量更难出错。

惰性求值是指在绝对必要之前不求值的函数。这意味着在不必要时可以避免许多操作。在基本的 C# if 子句中考虑这一点,例如:

if(IsSomethingTrue() && AnotherThingTrue())
{
    do something;
}
Run Code Online (Sandbox Code Playgroud)

如果IsSomethingTrue()为 false,则AnotherThingTrue()永远不会评估方法。

虽然 Haskell 是一种了不起的语言,但 F#(目前)的主要好处是它位于 CLR 之上。这使它适合多语言编程。有一天,您可能会在 ASP.net MVC 中编写 Web UI,在 C# 中编写业务逻辑,在 F# 中编写核心算法,在 Ironruby 中编写单元测试......所有这些都包含在 .Net 框架中。

收听 Simon Peyton Jones 的软件工程广播,了解有关 Haskell 的更多信息:第 108 集:Simon Peyton Jones 谈函数式编程和 Haskell

  • @JonHarrop:这是关于算法的声明,与编译器优化的适用性无关。如果确实需要,强制纯度语言通常允许您编写明确的不纯代码(如果没有别的,使用 FFI 调用 C)。当编译器不必保留(未知)副作用的顺序时,它可以更自由地应用代码转换。在“鼓励纯度”语言中,您编写的代码大多相似,因此相同的优化将适用,只是它们可能会使副作用无效(不存在,但编译器不能假设)。 (12认同)
  • 另一个值得指出的特点是,一种强制执行纯编程的语言,编译器在许多优化方面有更多的自由。像 F# 这样鼓励纯度但仍允许将未经检查的不纯操作丢弃在任何代码块中的语言会失去一些潜在的优化,因为编译器被迫假设每个调用都包含必要的副作用。 (9认同)
  • F# 的另一个潜在主要好处(视情况而定)是它不懒惰,这意味着对几乎每个人来说,推理时空行为的学习曲线都会简单得多。 (8认同)
  • 直接链接到 se-radio 第 108 集(西蒙佩顿琼斯):http://www.se-radio.net/podcast/2008-08/episode-108-simon-peyton-jones-functional-programming-and-haskell (5认同)
  • @JonHarrop 我什么时候声称它们都是算法?无论如何,我们比较的是 Haskell 和 F#,而不是 Haskell 和 C。F# 是一种“鼓励纯洁”的语言,因此您经常编写纯代码。我所声称的是,编译器通常可以在“强制纯度”设置中更好地优化*完全相同的代码*,因为 F# 编译器必须假设调用具有副作用。您正在谈论重写代码以使用不同的算法(取决于副作用的算法);我正在讨论 F# 与 Haskell 中纯代码的“可优化性”。 (3认同)

Nat*_*ers 53

大不同:

  • 平台
  • 面向对象
  • 懒惰

相同点比不同点更重要。基本上,如果您已经在使用 .NET,则应该使用 F#,否则应该使用 Haskell。此外,面向对象和懒惰意味着 F# 更接近您(可能)已经知道的内容,因此它可能更容易学习。

平台:Haskell 有自己的运行时,F# 使用 .NET。我不知道性能差异是什么,尽管我怀疑优化前的平均代码大致相同。如果您需要 .NET 库,F# 具有优势。

面向对象:F# 具有 OO,并且非常小心地确保 .NET 类易于使用,即使您的代码不是 OO。Haskell 有类型类,可以让你以一种奇怪的方式做类似面向对象的事情。它们就像与 Common Lisp 泛型函数交叉的 Ruby mixin。它们有点像 Java/C# 接口。

懒惰:Haskell 是懒惰的,而 F# 不是。懒惰带来了一些不错的技巧,并使一些看起来很慢的事情实际上执行得很快。但我发现猜测我的代码运行速度要困难得多。这两种语言都允许您使用其他模型,您只需在代码中明确说明它。

细微差别:

  • 语法:我认为 Haskell 的语法稍微好一些。它更简洁和规则,我喜欢在单独的行上声明类型。天啊。
  • 工具:F# 具有出色的 Visual Studio 集成,如果您喜欢那种东西。Haskell 也有一个较旧的 Visual Studio 插件,但我认为它从未退出测试版。Haskell 有一个简单的 emacs 模式,你大概可以使用 OCaml 的 tuareg-mode来编辑 F#。
  • 副作用:当改变变量时,这两种语言都非常明显。但是 Haskell 的编译器也强制您在使用它们时标记副作用。实际的区别在于,当您使用带有副作用的库时,您必须更加注意。


Mar*_*ade 35

F# 是 ML 语言家族的一部分,与 OCaml 非常接近。您可能想阅读有关Haskell 和 OCaml 之间差异的讨论。

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。- [来自评论](/review/low-quality-posts/10662537) (6认同)

Cur*_*son 33

一个主要的区别,可能是纯度的结果,但我很少看到提到,是 monad 的普遍使用。正如经常指出的那样,monad 可以用几乎任何语言构建,但是当它们在整个库中广泛使用时,生活就会发生很大的变化,并且您自己使用它们。

Monads 提供了在其他语言中以更有限的方式看到的东西:流控制的抽象。它们是做各种事情的非常有用和优雅的方式,一年的 Haskell 完全改变了我的编程方式,就像多年前从命令式编程到面向对象编程改变了它一样,或者,在很久以后,使用高阶函数确实如此。

不幸的是,在这样的空间中无法提供足够的理解来让您看到区别是什么。事实上,再多的写作也做不到;您只需要花足够的时间学习和编写代码即可获得真正的理解。

同样,当您与 .NET 平台/库交互时,F# 有时可能会变得功能性稍差或更笨拙(从函数式编程的角度来看),因为这些库显然是从 OO 的角度设计的。

所以你可能会这样考虑你的决定:你是想尝试这些语言中的一种以获得快速的、相对较小的改进增量,还是愿意投入更多的时间并获得较少的直接收益来获得更大的收益?长期。(或者,至少,如果您没有获得更大的东西,那么可以轻松快速地切换到另一个?)如果是前者,F# 是您的选择,如果是后者,则是 Haskell。

其他几个不相关的点:

Haskell 的语法稍微好一些,这并不奇怪,因为 Haskell 的设计者非常了解 ML。但是,F# 的“轻量级”语法在改进 ML 语法方面大有帮助,因此并没有太大的差距。

在平台方面,F#当然是.NET;我不知道它在 Mono 上的效果如何。GHC 使用自己的运行时编译为机器代码,在 Windows 和 Unix 下都能很好地工作,与 .NET 相比,C++ 的方式相同。在某些情况下,这可能是一个优势,尤其是在速度和较低级别的机器访问方面。(例如,我在 Haskell/GHC 中编写 DDE 服务器没有问题;我认为你不能用任何 .NET 语言来做到这一点,无论如何,MS 肯定不希望你这样做。)