Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Failed to load interface' error when loading compiled modules in ghci

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

like image 472
jules Avatar asked Dec 07 '13 21:12

jules


People also ask

How to load module in GHCi?

5.2. hs. Loading a multi-module program is just as straightforward; just give the name of the “topmost” module to the :load command (hint: :load can be abbreviated to :l). The topmost module will normally be Main, but it doesn't have to be.

How to quit GHCi?

Quits GHCi. You can also quit by typing control-D at the prompt. Attempts to reload the current target set (see :load ) if any of the modules in the set, or any dependent module, has changed.


1 Answers

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.

like image 149
asm Avatar answered Oct 06 '22 03:10

asm