2

我花了几天时间在 Haskell 中开发一个程序,同时学习这门语言。现在我意识到我需要调用 Arpack(一个 Fortran 库)或 Arpack++(一个对 Arpack 的 C++ 包装器)——我找不到带有 Haskell 绑定的 Lanczos 方法的良好实现。有没有更有经验的 Haskell 程序员知道这会有多困难?

我已经能够通过 Ubuntu 的存储库安装“.so”(“共享对象”)版本的 libarpack 和 libarpack++,但我不确定这是否足够。我怀疑我最终需要从源代码构建 Arpack++,这是可能的,但是我遇到了很多构建错误,所以这需要时间。有没有办法只使用“.so”文件,而不知道究竟是哪个版本的头文件用于生成它们?

我正在考虑使用 GreenCard,因为它看起来像是维护得最好的 Haskell/C 桥。不过我找不到太多文档,所以我想知道它是否也支持 C++。

我也开始怀疑是否应该用 Python 重写我的程序,并使用 scipy 调用 Arpack,但我已经花了几天时间来编写 Haskell。我也很喜欢 Haskell,所以我希望我能完成这项工作。我想我的总体问题是:使用 Haskell 进行这项工作会涉及什么?

非常感谢。

4

2 回答 2

1

我可以告诉你,在外部函数接口的帮助下,使用 Haskell 的 C/Fortran 库肯定是可能的,而且不会非常复杂。这是一个介绍。在我的理解中,您应该能够使用 C 调用约定调用任何东西,甚至可能是 Fortran,而无需重新编译代码。唯一的例外是看起来像函数调用但实际上是宏的东西,在这种情况下,您必须弄清楚宏的作用并在 Haskell 中重现它们。

至于绿卡,我从来没有用过,所以我不能保证。

您使用 Python 的第二个想法可能会为您节省几天以上的时间。可悲的是,我从来没有管理过 Haskell 代码来轻松适应我不断变化的需求,而我发现这在 Python 中微不足道。当然,这可能是对我使用 Haskell 的技能或我的思维过程的限制,而不是归咎于语言。

于 2012-08-07T04:34:24.080 回答
1

ELF 格式是可执行文件和共享库的标准格式,因此访问这些编译模块中的代码只需要知道函数名称即可。如果我理解正确,Fortran可以与 C 互操作。因此,Fortran 应该可以与任何可以使用 C 绑定的语言互操作,包括 Haskell。仅供参考,您可以使用工具找到模块(可执行或共享对象或简单对象存档)导出的所有名称(nm默认情况下,它通常在所有 linux 发行版中都可用)。如果二进制文件没有被“剥离”,这当然会起作用,但 AFAIK 这不是常见的做法。

然而,Haskell 不能以理智的方式使用 C++ 绑定,因为 C++ 多态特性需要名称修饰,并且这种名称转换的方法高度依赖于编译器。这是众所周知的问题,并非特定于 Haskell。当然,您可以尝试从 C++ 共享对象中获取导出符号的列表,然后使用 FFI 绑定它们,但是……这不值得。

正如 dsign 所说,您可以使用外部函数接口 GHC 功能来创建与外部代码的绑定。您所需要的只是库标题(当然还有库本身)。如果 C 语言是头文件 (*.h),但由于您的库是用 Fortran 编写的,您必须在库源中找到类似的头文件,请参阅此页面以匹配 Fortran 和 C 类型,然后使用此信息用于编写 FFI 绑定。首先编写 C 绑定会有所帮助,即编写 C 标头。然后你甚至可以使用像 c2hs 这样的自动 FFI 绑定程序。

查看 C++ 绑定可能也有帮助。它可能有我上面描述的头文件。如果它有一个,那么编写 FFI 绑定将不会比为任何其他库编写它们更困难。

因此,这并非完全不可能,但可能需要一些彻底的工作。为科学/纯计算库编写绑定比为一些系统库编写绑定要容易得多,这些系统库执行大量 IO 并保持自己的内部状态,但由于这个库不是用 C 编写的......好吧,可能建议把时间花在更简单的选择上。我不能对 scipy 说任何话,我从未使用过它,但由于 Python 作为一种语言比 Haskell 简单得多,它可能是一个不错的选择。

于 2012-08-07T07:26:23.257 回答