こんにちはHaskellコミュニティ、
私は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"
Cabalファイルのソース:
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-pkgcheck」は何も明らかにしません。
何が足りないのですか? Haskell 2010 Standard( http://www.haskell.org/onlinereport/haskell2010/haskellch5.html )で調べましたが、エラーが見つかりません。だから私の質問は
1)なぜこのエラーが発生するのですか?
2)そのような階層モジュールを構築することは良い習慣ですか? (かなり大きなプログラムを想定してください)
よろしくお願いします!
ジュール
編集:2016年9月
私が最初にこの質問に答えて以来、まだ公開されているFoo.Internal
モジュールを定義する慣行が増えています。以下の元の回答では、other-modules
フィールドを使用することを提案しました。現在普及している手法は、公開されているがサポートされているAPIの一部ではないFoo.Internal.*
モジュールを定義することです。このパターンの理論的根拠は、 この質問 への回答で説明されています。
コメントに記載されているように、.cabal
ファイルにother-modules
行がありません。 cabal install
は、FoodMod1
のみをインストールすると思います。
これは、たとえば、パッケージAPIで公開したくないcabalパッケージ全体で使用されるタイプを使用して内部モジュールを作成するための優れた方法です。 other-modules
モジュールはパッケージの外部からインポートできないため、パッケージのプライベート機能を作成できます。