haskellのstackを利用時に一部のパッケージをimport
し、そのままstack build
するとエラーとなりbuildに失敗することがあります。
前回投稿した記事
haskellのstackでghc-modを利用時に一部パッケージのimportでエラーとなる
に似た内容となっていますが
前回とはエラー発見のアプローチが違うということと、
前回までstack、haskellのpackageについてちゃんと理解していなかったということでお許しを。
ベース
今回プロジェクト名をmyappとしています。
module Main where
main :: IO ()
main = print "Hello, World"
以上でstack build
し実行すると、
"Hello, World"
と表示されます。
エラーとなる例
「すごいHaskellたのしく学ぼう」の中でも紹介されているモジュールから。
module Main where
import Data.List
import System.IO
import Control.Exception
import System.Directory
import System.Random
import Control.Monad.Writer
main :: IO ()
main = print "Hello, World"
のように6種類のモジュールをimportしてstack build
すると、
/dev/haskell/myapp/app/Main.hs:6:1: error:
Failed to load interface for ‘System.Directory’
It is a member of the hidden package ‘directory-1.2.6.2’.
Perhaps you need to add ‘directory’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
/dev/haskell/myapp/app/Main.hs:7:1: error:
Failed to load interface for ‘System.Random’
Use -v to see a list of the files searched for.
/dev/haskell/myapp/app/Main.hs:8:1: error:
Failed to load interface for ‘Control.Monad.Writer’
Perhaps you meant
Control.Monad.Fail (from base-4.9.0.0)
Control.Monad.Fix (from base-4.9.0.0)
Control.Monad.Zip (from base-4.9.0.0)
Use -v to see a list of the files searched for
のようなエラーが表示されました。
import System.Directory
import System.Random
import Control.Monad.Writer
の部分がエラーとなっているみたいです。
原因
stackではmyapp.cabal
の中で利用するパッケージを明記してやる必要があります。デフォルトでは、
executable myapp-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, myapp
default-language: Haskell2010
のように、base
とmyapp
パッケージだけが明記されています。(myappは自分のプロジェクト)
よって、このままではbaseに含まれるモジュールしか利用することができません。
baseパッケージには以下のモジュールが含まれています。
https://hackage.haskell.org/package/base
よって、baseパッケージに含まれていなかった、
import System.Directory
import System.Random
import Control.Monad.Writer
が失敗したというわけです。
解決策
よって、解決策としてはmyapp.cabal
に利用するパッケージを明記すればいいだけです。
先程のエラーを解決してみましょう。
System.Directory
,System.Random
,Control.Monad.Writer
はそれぞれ、
directory, random, mtlパッケージに属しているので、
executable myapp-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, myapp
+ , directory
+ , random
+ , mtl
default-language: Haskell2010
のように変更してやれば解決します。
#src以下、test以下 のファイルで同じエラーが発生する
上記の解決策ではapp
以下でのimport
のエラーしか解決できません。
src
以下、test
以下で同じように怒られるので、
src以下
library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
default-language: Haskell2010
test以下
test-suite myapp-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, myapp
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010
をapp
の時と同じようにbuild-depends
に必要なパッケージを追記してやれば解決します。