Haskell

haskellのstackでghc-modを利用時に一部パッケージのimportでエラーとなる

More than 1 year has passed since last update.

すごいH本の例をstackでやっていると本に登場するパッケージをimportするとghc-modに怒られました。
stackでghc-modを利用時に一部のパッケージをimportすると怒られるので、怒られないように設定します。

以下の例では、怒られた状態でstack runghcでの実行は成功しますが、stack buildでのビルドは失敗してしまいます。

怒られる例

ソース

Main.hs
module Main where

import System.Directory
import System.FilePath
import System.Random

main = putStrLn "hello, world"

ghc-modでcheck

$ghc-mod check app/Main.hs
app/Main.hs:3:1: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.
app/Main.hs:4:1:Failed to load interface for ‘System.FilePath’It is a member of the hidden package ‘filepath-1.4.1.0’.Perhaps you need to add ‘filepath’ to the build-depends in your .cabal file.Use -v to see a list of the files searched for.
app/Main.hs:5:1:Failed to load interface for ‘System.Random’It is a member of the hidden package ‘random-1.1’.Perhaps you need to add ‘random’ to the build-depends in your .cabal file.Use -v to see a list of the files searched for.

とこのように怒られてしまいました!!!

解決策

Perhaps you need to add ‘directory’ to the build-depends in your .cabal file.と言われている通り
解決策として、プロジェクト名.cabalファイルの一部を変更してstackにパッケージの依存関係を教えてやる必要があります。  
例として、怒られる例のSystem.Directory,System.FilePath,System.Random
についてimportで怒られないよう設定します。

デフォルトではプロジェクト名.cabalは以下のようになっています(一部抜粋)

プロジェクト名.cabal
executable プロジェクト名-exe
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , プロジェクト名
  default-language:    Haskell2010

これを以下のように変更します

プロジェクト名.cabal
executable プロジェクト名-exe
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , プロジェクト名
                     , directory
                     , filepath
                     , random
  default-language:    Haskell2010

ghc-modでcheck

$ghc-mod check app/Main.hs
$

OK!!

src以下、test以下 のファイルで同じエラーが発生する

上記の解決策ではapp以下でのimportのエラーしか解決できません。
src以下、test以下で同じように怒られるので、

src以下

プロジェクト名.cabal
library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
                     , directory
                     , filepath
                     , random
  default-language:    Haskell2010

test以下

プロジェクト名.cabal
test-suite プロジェクト名-test
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  build-depends:       base
                     , プロジェクト名
                     , directory
                     , filepath
                     , random
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

のようにappの時と同じようにbuild-dependsに追記してやれば解決します。
また、この状態でstack buildをするとビルドに成功します。

おまけ

atomエディタでlintツールを利用していると以下のように表示されます。

追記前
スクリーンショット 2016-12-21 21.07.19.png

追記後
スクリーンショット 2016-12-21 21.07.57.png