在Haskell中,我写了import Fruit
或import Fruit (apple)
,可以访问apple
或Fruit.apple
。
在Python中,我可以为from Fruit import apple
撰写apple
或为import Fruit
撰写Fruit.apple
。
我认为也可以在Python中编写import Fruit.apple as banana
来引用与banana
相同的函数。
如何在Haskell中这样做?两种语言中的import Fruit as Vegetable
都可以重命名Fruit,但我想重命名apple。
答案 0 :(得分:18)
这是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
的推断类型可能不如预期的多态。
Monomorphism限制尝试为每个顶级函数分配一个类型类的具体实例(这是出于性能原因而完成的)。考虑,
example = return ()
此函数应具有类型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
与[{1}}
答案 1 :(得分:7)
没有直接的语法。大概你想避免与本地定义的apple
发生冲突,所以我会选择
import qualified Fruit (apple)
banana = Fruit.apple