この記事では、HaskellのStackを使っている人向けに、自分で書いたmoduleをstack buildコマンドでビルドする方法を紹介します。
Stackの基本的な使い方は下記を参照してください:
前提
標準のテンプレートでプロジェクトを作った場合で説明します。例えば
$ stack new sample-project
でプロジェクトを作ったとします。
(もしsample-projectの後ろの引数に何かを指定していた場合は、それは標準でない別のテンプレートを指定したことになるので注意してください。)
ディレクトリの構造
標準テンプレートでstack newすると、下記のようなディレクトリ構造になるはずです:
$ tree
.
├── LICENSE
├── Setup.hs
├── app
│   └── Main.hs  # main関数がある
├── sample-project.cabal  # あとで編集する
├── src
│   └── Lib.hs   # 標準のライブラリ用ソースファイル
├── stack.yaml
└── test
    └── Spec.hs
3 directories, 8 files
やり方
1. moduleを含むファイルを作る
まず、何かmoduleを含んだ新しいソースファイル(.hs)をsrcディレクトリ以下に作ります。
この際、 module名とファイル名(.hs)は一致させる ようにしてください。例えばmodule MyModuleを定義する場合は、そのファイル名はMyModule.hsです。(要するに、Javaのpublicクラスに似たルールです)
module MyModule where
myFunc :: String -> String
myFunc s = "これは" ++ s ++ "です。"
2. sample-project.cabalを編集する
次に、プロジェクト内のsample-project.cabalを編集します。
セクションlibraryの中のexposed-modulesに先ほど作ったmoduleの名前を記入します:
library
  hs-source-dirs:      src
  exposed-modules:     Lib, MyModule
  build-depends:       base >= 4.7 && < 5
  default-language:    Haskell2010
3. 他のソースコードに自作moduleを取り込む
おそらく自分でmoduleを作る場合は、他のソースコードにimportすることが目的のはずです。
今回は同じsrcディレクトリに標準で入っているLib.hsにMyModuleを取り込んでみます。
module Lib
    ( someFunc
    ) where
import MyModule
someFunc :: IO ()
someFunc = putStrLn $ myFunc "テスト"
main関数のあるapp/Main.hsはデフォルトのままです。
module Main where
import Lib
main :: IO ()
main = someFunc
4. ビルド&実行する
最後に、通常通りビルド&実行を行います。
なお、stack execで実行できるのは、sample-project.cabalのexecutableとして書かれているもののみです。
executable sample-project-exe
  hs-source-dirs:      app
  main-is:             Main.hs
$ stack build
$ stack exec sample-project-exe
これはテストです。
以上です。