一部パッケージimportでstack buildできない

haskellのstackを利用時に一部のパッケージを`import`し、そのまま`stack build`するとエラーとなりbuildに失敗することがあります。

前回投稿した記事
[haskellのstackでghc-modを利用時に一部パッケージのimportでエラーとなる](http://qiita.com/katsuyan/items/a132d7bf6817f19af2d6)
に似た内容となっていますが

前回とはエラー発見のアプローチが違うということと、
前回までstack、haskellのpackageについてちゃんと理解していなかったということでお許しを。

# ベース
今回プロジェクト名をmyappとしています。

```Main.hs
module Main where

main :: IO ()
main = print "Hello, World"
```

以上で`stack build`し実行すると、

```
"Hello, World"
```

と表示されます。

# エラーとなる例
「すごいHaskellたのしく学ぼう」の中でも紹介されているモジュールから。

```Main.hs
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`の中で利用するパッケージを明記してやる必要があります。デフォルトでは、

```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パッケージに属しているので、

```diff
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以下

```myapp.cabal
library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
  default-language:    Haskell2010
```

test以下

```myapp.cabal
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`に必要なパッケージを追記してやれば解決します。