web-dev-qa-db-ja.com

コンパイルされたモジュールをghciにロードするときに「インターフェイスのロードに失敗しました」エラー

こんにちは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)そのような階層モジュールを構築することは良い習慣ですか? (かなり大きなプログラムを想定してください)

よろしくお願いします!

ジュール

14
jules

編集:2016年9月

私が最初にこの質問に答えて以来、まだ公開されているFoo.Internalモジュールを定義する慣行が増えています。以下の元の回答では、other-modulesフィールドを使用することを提案しました。現在普及している手法は、公開されているがサポートされているAPIの一部ではないFoo.Internal.*モジュールを定義することです。このパターンの理論的根拠は、 この質問 への回答で説明されています。


コメントに記載されているように、.cabalファイルにother-modules行がありません。 cabal installは、FoodMod1のみをインストールすると思います。

これは、たとえば、パッケージAPIで公開したくないcabalパッケージ全体で使用されるタイプを使用して内部モジュールを作成するための優れた方法です。 other-modulesモジュールはパッケージの外部からインポートできないため、パッケージのプライベート機能を作成できます。

9
asm