42

如果您有可能拥有一个同时使用 Haskell 和 C++ 的应用程序。你会让 Haskell 管理哪些层,让 C++ 管理哪些层?

有没有人做过这样的关联,(肯定)?

(Haskell 网站告诉它真的很容易,因为 Haskell 有一种模式,它可以通过 gcc 在 C 中编译)

起初我认为我会将所有 I/O 操作保留在 C++ 层中。以及 GUI 管理。

这是一个非常模糊的问题,但是当我计划学习 Haskell 时,我正在考虑将一些工作委派给 Haskell 代码(我在实际编码中学习),并且我想选择一些我会看到 Haskell 好处的部分。

4

4 回答 4

28

Haskell 的好处是它允许您使用强大的抽象。您考虑的不是 1 和 0 以及地址和寄存器,而是计算、类型属性和延续。

C++ 的好处是您可以在必要时对其进行优化。您不会考虑高尚的 monad、箭头、部分应用程序和组合纯函数:使用 C++,您可以直接接触到裸机!

这两种说法之间存在张力。Donald Knuth在他的论文“Structured Programming with statements”中写道go to

很长一段时间以来,我一直认为,编程的天赋主要在于能够轻松地从事物的微观视角切换到宏观视角,流畅地改变抽象层次。

知道如何使用 Haskell 和 C++ 以及如何以及何时它们很好地结合起来会解决各种问题。

我写的最后一个使用FFI的大型项目涉及使用用 C 编写的内部雷达建模库。重新实现它会很愚蠢,并且表达应用程序其余部分的高级逻辑会很痛苦。我将它的“大脑”保存在 Haskell 中,并在需要时调用 C 库。

您想将此作为练习,所以我推荐相同的方法:在 Haskell 中编写 smarts。将 Haskell 束缚为 C++ 的奴隶可能最终会让你感到沮丧,或者让你觉得自己在浪费时间。使用每种语言的优势所在。

于 2010-08-22T13:16:28.310 回答
11

以下是我的看法:

  • 函数式语言擅长转换事物。每当您编写接受输入并对其进行映射/过滤/减少的程序时,请使用功能构造。Web 应用程序给出了 Haskell 应该擅长的精彩现实世界示例(您基本上将存储在数据库中的内容转换为网页)。
  • 过程语言(OOP 语言过程语言)擅长副作用和对象之间的通信。使用它们来转换数据很麻烦,但是当您想要进行系统编程或与人类(任何类型的用户界面,包括客户端 Web 编程)进行(双向)交互时,它们可以干净地完成工作。
  • 然而,有些人可能会争辩说用户界面应该有一个功能描述,我回答说,完善的框架很容易与 OOP 语言一起使用,人们应该以这种方式使用它们。毕竟,从对象和对象之间的通信的角度来考虑 UI 组件是很自然的。
  • IO 只是一个工具:每当您将输入转换为输出时,Haskell(或任何 FP 语言)都应该执行 IO。每当您与人交谈时,C++(或任何 OOP 语言)都应该进行 IO。
  • 不要在意速度。当您将 Haskell 用于正确的工作时,它是高效的。当您将 C++ 或 Python 用于正确的工作时,它是高效的。

因此,假设我精通 Haskell、C、C++ 和 Python,以下是我编写应用程序的方式:

  • 如果我的应用程序的主要角色是转换数据,我用 Haskell 编写它,可能有一些用 C 编写的低级部分(反过来,可能会调用一些用 C++ 编写的高科技低级部分,但我会坚持出于可移植性的原因,使用 C 作为接口)。
  • 如果我的应用程序的主要角色是与用户交互,我用 Python(例如 PyQt)编写它,并让 Python 调用用 C++ 编写的性能关键例程(boost::python 作为绑定生成器非常好)。我可能还必须调用转换或获取数据的子例程,这些子例程将用 Haskell 编写。
  • 如果我必须在 Haskell 中编写应用程序的一部分,我会将其隔离到 C 可调用的 API 中。
  • 有时,在标准输入上读取内容并在标准输出上回写的 Haskell 应用程序可用作子模块(您使用 fork/exec 或平台上的任何东西调用)。有时,shell 脚本是此类应用程序的正确包装器。
于 2010-11-08T11:08:29.250 回答
7

这个答案更像是一个故事而不是一个全面的答案,但我在计算语言学的论文中使用了 Haskell、Python 和 C++ 的组合,以及我没有编写的几个 C 和 Java 工具。我发现将所有内容作为一个单独的进程运行最简单,使用 Python 作为胶水代码来启动 Haskell、C++ 和 Java 程序。

C++ 是一个相当简单、紧密的循环,可以计算特征的出现次数。基本上它所做的只是数学和简单的 I/O。我实际上是通过让 Python 胶水代码写出一个充满#defines 的标头并重新编译来控制选项。有点hacky,但它有效。

Haskell 是所有中间处理:从我使用的各种 C 和 Java 解析器中获取复杂的输出,过滤无关数据,并将其转换为 C++ 代码所期望的简单格式。然后我将 C++ 输出转换为 LaTeX 标记(以及其他格式)。

这是您期望 Python 强大的领域,但我发现 Haskell 使复杂结构的操作更容易;Python 可能更适合于简单的行到行转换,但我正在对解析树进行切片和切块,发现在 Python 中编写代码时忘记了输入和输出类型。

因为我使用 Haskell 很像一种结构化的脚本语言,所以我最终编写了一些文件 I/O 实用程序,但除此之外,用于树和列表操作的内置库就足够了。

总之,如果您遇到像我这样的问题,我建议 C++ 用于内存受限、速度关键的部分,Haskell 用于高级转换,而 Python 来运行它。

于 2010-08-22T22:07:48.140 回答
5

我从来没有混合过两种语言,但你的方法对我来说有点颠倒。Haskell 更适合高级操作,而 C++ 可以进行优化,并且最有利于紧密循环和其他性能关键代码。

Haskell 的最大好处之一是将 IO 封装到 monad 中。只要这个 IO 不是时间紧迫的,我看不出有任何理由在 C++ 中这样做。

对于 GUI 部分,您可能是对的。有大量的 Haskell GUI 库,但 C++ 具有强大的工具,例如 QtCreator,可以大大简化繁琐的任务。

于 2010-08-22T10:39:42.903 回答