在ghci中加载编译模块时'加载接口失败'错误 [英] 'Failed to load interface' error when loading compiled modules in ghci
问题描述
Hello Haskell社区,
我是Haskell的新手,在尝试构建我的第一个更大的项目时遇到了问题。
这是问题的最小例子(我正在使用cabal编译)。
这是一个简单模块的目录结构:
FooMod1
| - FooMod1.cabal
| - Setup.hs
| - src
| - FooMod1.hs
| - FooMod1
| - C1.hs
| - T1.hs
FooMod1.hs的源代码:
module FooMod1(
C1(..),
T1(..),
)其中
import FooMod1.C1
import FooMod1.T1
C1.hs的源代码:
module FooMod1.C1(
C1(..)
)其中
class C1 a其中
c1FooFun :: a - > IO()
T1.hs的源代码:
module FooMod1.T1(
T1(..)
)其中
import FooMod1.C1
数据T1 = T1派生(显示)
实例C1 T1其中
c1FooFun T1 = putStrLn来自T1的c1FooFun
cabal文件的源代码:
名称:FooMod1
版本:0.0.1
Cabal-version:> = 1.10
构建类型:简单
库
build-depends:base> = 4&& < 5
如果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:
模块Main其中
import Distribution.Simple
main = defaultMain
我可以做
$ b $
cabal configure
cabal build
cabal install
没有任何问题。当我启动ghci和
import FooMod1
它加载模块,我可以看到数据构造函数。
但是当我尝试获取函数的类型时,例如
:t c1FooFun
code>
或者构造一个我得到的值:
无法加载`FooMod1.C1'接口
'FooMod1-0.0.1'包中缺少文件,
尝试运行'ghc-pkg check'。
使用-v查看搜索的文件列表。
在表达式中:c1FooFun
'ghc-pkg check'没有任何显示。
我错过了什么?我查看了Haskell 2010标准版( http://www.haskell.org/onlinereport/haskell2010/haskellch5。 HTML ),我找不到错误。所以我的问题是:
$ b $ 1)为什么我会得到这个错误?
<2>正在构建一个分层模块像那种好习惯? (假设有相当大的节目)
非常感谢您!
Jules
编辑:2016年9月
自从我最初回答这个问题以来,越来越多的做法是定义 Foo.Internal
仍然暴露的模块。在下面的原始答案中,我建议使用 other-modules
字段。现在流行的做法是定义 Foo.Internal。*
模块,这些模块是公开的,但明确地不属于受支持的API。这个模式的理由在这个问题的答案中解释。
正如注释中所指出的那样, .cabal
文件缺少 other-modules
行。我认为
cabal install
然后只安装 FoodMod1
,因为这已经被告知了。
这是一个很好的创建内部模块的方法,例如,在您不想在包API中公开的cabal包中使用的类型。由于 other-modules
模块不能从包装外部导入,因此它允许您创建包装专用功能。
Hello Haskell community,
I'm new to Haskell and ran into a problem when I tried to structure my first bigger project.
Here's the minimal example of the problem (I'm using cabal to build).
This is the directory structure of a simple module:
FooMod1
|- FooMod1.cabal
|- Setup.hs
|- src
|- FooMod1.hs
|- FooMod1
|- C1.hs
|- T1.hs
The source for FooMod1.hs:
module FooMod1 (
C1(..) ,
T1(..) ,
) where
import FooMod1.C1
import FooMod1.T1
The source for C1.hs:
module FooMod1.C1 (
C1(..)
) where
class C1 a where
c1FooFun :: a -> IO ()
The source for 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"
The source for the cabal file:
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
and the Setup.hs:
module Main where
import Distribution.Simple
main = defaultMain
I can do
cabal configure
cabal build
cabal install
without any problem. When I start ghci and
import FooMod1
it loads the module and I can see the data constructors. But when I try to get the type of a function for example
:t c1FooFun
or construct a value I get:
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 check' reveals nothing.
What am I missing? I looked it up in the Haskell 2010 Standard (http://www.haskell.org/onlinereport/haskell2010/haskellch5.html) and i can't find the error. So my questions are
1) Why am I getting this error?
2) Is structuring a hierarchical modules like that good practice? (assume considerably larger programs)
Many thanks in advance!
Jules
Edit: September 2016
Since I originally answered this question there is a growing practice of defining Foo.Internal
modules that are still exposed. In the original answer below I suggested using the other-modules
field. A practice that is now popular is to define Foo.Internal.*
modules that are exposed but explicitly not part of the supported API. The rational for this pattern is explained in the answers to this question.
As noted in the comments your .cabal
file is missing the other-modules
line. I think cabal install
then only installs FoodMod1
since that is all it's been told about.
This is a nice way to create internal modules with, for instance, types that are used throughout your cabal package which you don't want to expose in the package API. Since the other-modules
modules cannot be imported from outside your package it allows you to create package private functionality.
这篇关于在ghci中加载编译模块时'加载接口失败'错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!