别名在Haskell中的同一文件中定义的模块

时间:2016-02-24 17:16:04

标签: haskell

我有一个类似的模块:

module Foo.Bar (
  Bar,
  not
) where
data Bar = Some Int | Other Int
not (Some x) = ...
not (Other x) = Foo.Bar.not $ Some x

如您所见,我必须写Foo.Bar.not,因为not中定义了Prelude

有没有办法将Foo.Bar替换为例如Bnot (Other x) = B.not $ Some x以便我可以在not定义的文件中写setValue

5 个答案:

答案 0 :(得分:2)

我认为在GHC中,如果有点痛苦,技术上应该是可行的。例如,如果您生成以下两个文件(documentation on mutual recursion之后),我希望事情能够正常工作:

-- Foo/Bar.hs-boot
module Foo.Bar where
import Prelude(Either)
not :: Either a a -> a

-- Foo/Bar.hs
module Foo.Bar where
import Prelude (Either(..))
import {-# SOURCE #-} Foo.Bar as B
not (Left x) = x
not (Right x) = B.not (Left x)

但是,当我尝试此操作时,我会收到B.not不在范围内的投诉。我怀疑这是GHC中的一个错误,并且已经提交了一张票here来查看开发者是否同意。

答案 1 :(得分:2)

  

有没有办法将Foo.Bar替换为例如Bnot [...]?

虽然我不确定是否有办法为模块添加别名,但您可以轻松地为module Foo.Bar ( Bar, Foo.Bar.not ) where data Bar = Some Int | Other Int notBar, not :: Bar -> Bool notBar (Some x) = ... notBar (Other x) = notBar (Some x) -- Use 'notBar' in this module, but export only 'not'. not = notBar 添加别名:

notBar

鉴于B.notPrelude长度不同,我认为这或多或少是一个有效的解决方案。此外,它并不依赖于任何编译器怪癖。

或者,隐藏使用module Foo.Bar ( Bar, not ) where import Prelude hiding (not) data Bar = Some Int | Other Int not :: Bar -> Bool not (Some x) = ... not (Other x) = notBar (Some x)

中相同名称的绑定
$variable = implode('',$dizi);

Outputs: $variable = 247;

答案 2 :(得分:1)

这是一个GHC兼容的答案,虽然它有点紧张:

-- B.hs
module B (
  Bar,
  B.not
) where
data Bar = Some Int | Other Int
not (Some x) = undefined
not (Other x) = B.not $ Some x
-- Foo.Bar.hs
module Foo.Bar (module Foo.Bar) where
import B as Foo.Bar

导入Foo.Bar后,会提供BarnotFoo.Bar.BarFoo.Bar.not(如果Foo.Barvoid foo1(MatrixXd& container){ //...container matrix is modified here } ,前两个会被取消进口合格。)

答案 3 :(得分:0)

这应该有效

module Foo.Bar (
  Bar,
  B.not
) where

import qualified Foo.Bar as B (not)

data Bar = Some Int | Other Int
not (Some x) = undefined
not (Other x) = B.not $ Some x
但请注意,如果你使用的是GHC,你可能需要做一些额外的工作:https://wiki.haskell.org/Mutually_recursive_modules#GHC

答案 4 :(得分:0)

似乎使用符合Haskell规范并在GHC中工作的任何东西都不可能。

无论如何,有一些方法可以实现类似的结果:

  • 作为@leftaroundabout pointed outimport Prelude hiding (not)会有所帮助。
  • @PyRulez'answer建议创建一个名为B的模块,并在Foo.Bar
  • 中导出该模块
  • @ Zeta answer建议将Foo.Bar.not别名化为notBar