23

在 Haskell 中,我编写import Fruitorimport Fruit (apple) 并且可以访问appleor Fruit.apple

在 Python 中,我可以编写from Fruit import appleforappleimport Fruitfor Fruit.apple

我认为也可以用import Fruit.apple as bananaPython 编写来引用与banana.

我如何在 Haskell 中做到这一点?import Fruit as Vegetable任何一种语言都可以重命名水果,但我想重命名苹果。

4

2 回答 2

23

这是 Python 的一个很好的属性,因为它的“字典一直向下”可以这么说。Haskell 允许您为模块分配别名,但无法从import语句中为函数指定别名(据我所知)。你能做的最好的就是

import qualified Fruit as F (apple)
banana = F.apple

你可以把它放在它自己的模块中并导出你想要的值,隐藏所有这些的细节,但对于如此简单的事情来说,这似乎需要做很多工作。

正如 hammar 在下面评论的那样,单态限制可能会导致banana. 为了安全起见,您应该使用banana所需的类型(可能是apple)进行注释,或者禁用单态限制为

{-# LANGUAGE NoMonomorphismRestriction #-}
import qualified Fruit as F (apple)
banana = F.apple

否则,推断的类型的banana多态性可能低于预期。

单态限制尝试为每个顶级函数分配一个类型类的具体实例(这是出于性能原因)。考虑,

example = return ()

这个函数应该有 type Monad m => m (),但是由于单态性的限制,没有足够的信息来说明应该使用哪个 Monad 实例,所以你会得到以下消息

Ambiguous type variable `m0' in the constraint:
  (Monad m0) arising from a use of `return'
Possible cause: the monomorphism restriction applied to the following:
  example :: m0 () (bound at Test.hs:44:1)
Probable fix: give these definition(s) an explicit type signature
              or use -XNoMonomorphismRestriction
In the expression: return ()
In an equation for `example': example = return ()

现在,如果您为 GHC 提供了足够的信息来推断您正在使用哪个 Monad 实例,例如

example = return ()

main :: IO ()
main = example

那么GHC会给出以下类型

*Main> :t example
example :: IO ()

因为你告诉它将example具有相同的类型main

于 2012-09-29T19:50:54.147 回答
7

没有直接的语法。大概你想避免与 local-defined 发生冲突apple,所以我会选择

import qualified Fruit (apple)
banana = Fruit.apple
于 2012-09-29T19:58:52.290 回答