混合Haskell和C++

Ste*_*and 37 c++ haskell ffi

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

有没有人做过这样的联想,(当然)?

(Haskell站点告诉它非常简单,因为Haskell有一个模式,可以通过gcc在C中编译)

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

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

Gre*_*con 26

Haskell的好处是它允许您使用的强大抽象.你不是在考虑一个零和零,地址和寄存器,而是计算和类型属性和延续.

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

这两个陈述之间存在紧张关系.唐纳德克努特在他的论文"结构化编程与go to陈述"中写道

我已经感觉很长一段时间了,编程才能很大程度上取决于从微观到宏观视角切换的能力,能够流畅地改变抽象层次.

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

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

你想做这个练习,所以我建议采用相同的方法:在Haskell中编写智能.束缚Haskell作为C++的奴隶可能最终会让你感到沮丧,或者让你感觉好像浪费了你的时间.使用每种语言的优势所在.

  • 并且对于Knuth的文章而言,(基本面从未受到伤害).虽然它不是通过ACM免费提供的(我在那里没有帐户),但可以在CiteSeerx下载 (2认同)
  • @Stephane我们使用的语言[塑造我们的思维](http://en.wikipedia.org/wiki/Linguistic_relativity).C++的命令式根源往往会使程序的表达陷入困境,并且[模式是编程语言中弱点的表现.](http://blog.plover.com/prog/design-patterns.html)移入声明性方向,脚手架消失,留下精华,这很容易推理.当然,在Cask中编写漂亮的程序和在Haskell中编写丑陋的程序仍然是可能的,但学习多种范例将使你成为更好的程序员. (2认同)
  • @Stephane Rolland:如果你想学习Haskell,那就去学习Haskell,然后回来问问题."如何学习Haskell?"之间存在差异?和"如何互操作Haskell和C++?".@gbacon:我不打算暗示你是在抨击C++,只是因为我觉得你对它的高级设施有不公正的看法,我当然同意多种范式更强. (2认同)

Ale*_* C. 11

这是我看到的东西:

  • 功能语言擅长改造事物.每当你编写输入并映射/过滤/减少它的程序时,使用功能结构.Haskell应该优秀的精彩真实世界示例由Web应用程序提供(您基本上将存储在数据库中的内容转换为网页).
  • 程序语言(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.
  • 有时候,在stdin上读取东西并在stdout上回写的Haskell应用程序可用作子模块(用fork/exec或平台上的任何东西调用).有时,shell脚本是此类应用程序的正确包装器.


Nat*_*ers 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用于运行它.

  • 我的程序是一个批处理操作,没有GUI,所以除了通过文件之外,C++和Haskell根本没有相互通信.我使用Python的subprocess.Popen开始它们,所以我可以最大限度地利用我的机器上的核心.因此Python也没有真正与其他人交谈.但我发现我不需要太多的C++ - 只有中央,大多数占用内存的算法.如果您需要大量的C++,或者您需要在程序的各个部分之间进行紧密合作,那么我的方法可能效果不佳. (2认同)

pmr*_*pmr 5

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

Haskell最大的好处之一是将IO封装到monad中.只要这个IO不是时间关键的,我就没有理由在C++中做到这一点.

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

  • 我不认为pmr这么说.你问相对的优势是什么 - 而pmr的答案非常准确.如果你对命令式的风格感觉更舒服,那很好.但这是你自己的感觉,而不是对语言擅长的比较,这是你最初要求的. (3认同)