2017-02-22 185 views
3

我有這樣的代碼是否有可能在Haskell中有子模塊?

module M where 

a = 1 
b = 2 
x = 10 
y = 20 

...但作爲模塊的增長就很難對付重名。

是否有可能有這樣的命名空間?

module M where 
    module A where 
    a = 1 
    b = 2 

    module X where 
    x = 10 
    y = 20 

..和再

... 
import M 

s = A.a + X.y 
+0

「模塊A.B在哪裏」有什麼問題? –

+0

另請參閱[揹包](http://blog.ezyang.com/2016/10/try-backpack-ghc-backpack/),這是一項正在開展的最新GHC工作。 – luqui

+1

我有一個模塊,它定義了一些記錄,爲了避免名稱衝突,我想我可以將子模塊中的記錄進行分組。 – vidi

回答

9

你什麼建議目前不支持在Haskell AFAIK。也就是說,沒有任何東西阻止你創建看似命名空間的模塊。例如:

module Top where 

myTopFunc :: a -> Int 
myTopFunc _ = 1 

,並在另一個文件:

module Top.Sub where 

mySubFunc :: a -> String 
mySubFunc _ = "Haskell" 

除了這個,你有幾個技巧你的袖子來安排你的模塊。如果將模塊A導入B,則可以將A的可見實體從B導出,就好像它們是自己的一樣。隨後,在導入B時,您將能夠使用這些函數/數據類型等,而不會意識到它們最初來自哪裏。使用上述模塊的示例如下:

module Top (
    myTopFunc, 
    TS.mySubFunc 
) where 

import qualified Top.Sub as TS 

myTopFunc :: a -> Int 
myTopFunc _ = 1 

現在,只需通過導入Top即可使用這兩種功能。

import Top (myTopFunc, mySubFunc) 
+1

第二個示例是我能夠想到的最接近的翻譯,即原始pseuo-Haskell。 'M'成爲'M.Core'等,'A' /'B' - >'M.A' /'M.B'和一個新的模塊'M'只需重新輸出所有的定義。 – user2407038

4

有層次模塊。您可以擁有名爲MM.AM.X的模塊,但就語言而言,模塊本身不會嵌套,並且MM.A無關。

如果你想M導出一切M.AM.X出口,你必須明確地做到這一點:

module M (module M.A, module M.X) where 
import M.A 
import M.X 
-- rest of M 
1

你就是不行。但是你的評論提到你只是在尋找一種避免命名衝突的方法。爲此,您可以使用{-# LANGUAGE DuplicateRecordFields #-}擴展名,編譯器將允許重複的記錄字段名稱。

+0

我知道這個擴展,但它不起作用,如果我使用makeLenses爲我的記錄生成Lens – vidi

+0

@vidi是的,當我偶然發現它和你的問題時,我正在尋找同樣的東西。事實上,它非常有限。它看起來像PureScript更好地支持常規記錄類型的東西;作爲實現Web服務的Haskell的新手,我想我可能會更多地研究PureScript。 –