2013-12-07 45 views
14

你好哈斯克爾社區,「無法加載接口」在ghci中加載編譯的模塊

我是新來的Haskell和遇到了一個問題,當我試圖構建我的第一個大項目時的錯誤。

這是問題的最小例子(我正在使用cabal來構建)。

這是一個簡單的模塊的目錄結構:

FooMod1 
|- FooMod1.cabal 
|- Setup.hs 
|- src 
    |- FooMod1.hs 
    |- FooMod1 
    |- C1.hs 
    |- T1.hs 

爲FooMod1.hs源:

module FooMod1 (
    C1(..) , 
    T1(..) , 
) where 

import FooMod1.C1 
import FooMod1.T1 

源爲C1.hs:

module FooMod1.C1 (
    C1(..) 
) where 

class C1 a where 
    c1FooFun :: a -> IO() 

的T1.hs的源代碼:

module FooMod1.T1 (
    T1(..) 
) where 

import FooMod1.C1 

data T1 = T1 deriving(Show) 

instance C1 T1 where 
    c1FooFun T1 = putStrLn "c1FooFun from T1" 

爲小集團文件的源:

Name:      FooMod1 
Version:     0.0.1 
Cabal-version:    >=1.10 
Build-type:    Simple 

library 
    build-depends:   base >= 4 && < 5 
    if impl(ghc >= 7.0.0) 
    default-language:  Haskell2010 
    ghc-options:    -Wall 
    exposed-modules:   FooMod1 

    ghc-options:    -Wall -rtsopts 
    hs-source-dirs:   src, src/FooMod1 
    default-language:  Haskell2010 

和Setup.hs:

module Main where 

import Distribution.Simple 

main = defaultMain 

我可以做

cabal configure 
cabal build 
cabal install 

沒有任何問題。當我啓動ghci和

import FooMod1 

它加載模塊,我可以看到數據構造函數。 但是,當我試圖讓一個函數的類型,例如

:t c1FooFun 

或構建一個值,我得到:

Failed to load interface for `FooMod1.C1' 
There are files missing in the `FooMod1-0.0.1' package, 
try running 'ghc-pkg check'. 
Use -v to see a list of the files searched for. 
In the expression: c1FooFun 

「GHC-PKG檢查」揭示了什麼。

我錯過了什麼?我在Haskell 2010標準(http://www.haskell.org/onlinereport/haskell2010/haskellch5.html)中查找它,我找不到錯誤。所以我的問題是

1)爲什麼我得到這個錯誤?

2)正在構建一個類似於良好實踐的分層模塊嗎? (假設相當大的程序)

非常感謝提前!

+3

我想你的cabal文件丟失了'other-modules:'行。你只告訴它關於'FooMod1'模塊。我不知道爲什麼這不是編譯錯誤。 – asm

+0

@ Andrew:非常感謝您這是問題所在......您是否可以將解決方案轉貼爲答案,以便我可以接受它? – jules

回答

7

編輯:2016年9月

因爲我本來回答了這個問題有定義Foo.Internal模塊仍然面臨的越來越多的做法。在下面的原始答案中,我建議使用other-modules字段。目前流行的一種做法是定義Foo.Internal.*模塊,這些模塊已公開但顯式不屬於受支持的API。在this question的回答中解釋了這種模式的合理性。


正如評論中的.cabal文件丟失other-modules行指出。我認爲cabal install然後只安裝FoodMod1,因爲這是所有它被告知。

這是一個很好的創建內部模塊的方法,例如,整個cabal包中使用的類型,您不希望在包API中公開。由於other-modules模塊無法從包裝外部導入,因此您可以創建包裝專用功能。