所有的 Haskell 包都相互兼容吗?

3

我在这里看到很多Haskell的包:

http://hackage.haskell.org/packages/archive/pkg-list.html#cat:database

这些包都彼此兼容吗?如果我引入了10个包来构建程序,它们是否都可以正常工作?如果我引入了页面上列出的所有包,会怎样呢?

假设您在Java中,如果从网络上引入10个JAR文件,这些文件之间可能存在依赖关系,导致一个JAR需要另一个不是其他JAR的良好版本的Hibernate版本。例如,一个JAR可能需要Hibernate 3.0.0版本,而另一个需要Hibernate 2.0.0版本。因此,我不能使用这两个JAR文件,因为它们没有使用共同的Hibernate版本。


你尝试过只是导入和编译吗? - aldo.roman.nurena
这并不是测试它们是否兼容的好方法。在Java中,如果我导入并编译,即使它可能会编译通过,但因为一个JAR依赖于另一个JAR的非常旧的版本,接口可能相同,但代码行为可能会有所不同。 - Phil
@Phil 在Haskell中,兼容接口但行为改变的危险比Java要小得多,这是因为Haskell是纯函数式编程语言。Java库依赖于传递的对象处于正确的状态,并且可能在侧面更新该状态,而Haskell(大多数情况下)没有具有可变状态的对象,函数只是返回其广告类型的值。通常这意味着,在给定类型签名的情况下,它只能做一件“明智”的事情,因此任何行为上的更改而没有接口更改只能是错误修复。理论上你是正确的。 - Ben
这比Java/Scala更适合模块兼容性,因为在Java/Scala中有OSGi,但许多项目不会在OSGi中发布。有Maven或SBT(Simple Build Tool),但没有保证任何模块可以一起工作,除非手动查看依赖项。 - Phil
2个回答

6

不会,但是

  1. 所有的包都声明了依赖,包括版本范围
  2. 如果你使用cabal-install,它会尽最大努力保持一致性。大部分情况下它做得很好。我曾经因为依赖旧版本而无法构建软件,但从未见过cabal被骗的情况。如果cabal为您安装了包,它就能工作;而且cabal可能会为您安装包。

6
您在Haskell中也会遇到同样的问题,尽管Cabal在解决依赖关系方面异常聪明。Cabal可以愉快地安装多个版本的软件包,但是当您创建自己的软件包时,这可能会导致一个微妙的错误:您的软件包可能间接地依赖于多个版本(当执行configure时,Cabal会警告您),这会带来一个微妙的惊喜:当您间接引用(例如通过类型推断)一个类型,比如State,它可能在一个地方被解析为mtl 1.x,在另一个地方被解析为mtl 2.x,而且这两者无法统一。当您使用两个软件包并想将它们组合在您的代码中时,这就成为了一个问题。虽然这很少见,但还是值得注意的。
此外,请注意,Haskell软件包通常依赖于版本范围而不是单个版本。这意味着Cabal构建接受版本的交集并使用其中最新的版本。

2
幸运的是,您所描述的问题在编译时就会显现出来; GHC 不会构建一个试图在不同包版本之间隐式转换数据的模块。 - John L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接