1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Haskell でプロジェクトを作成する方法( stack を利用 )

Posted at

Haskell のプロジェクト作成を stack で行いました
Haskell のビルドツールは cabal との2択のようでしたが stack の方が後発とのことで stack を選びました

プロジェクトの作成とユニットテストができるところまでやっています

環境

  • macOS 11.6
  • zsh 5.8
  • stack 2.7.5

stack のインストール

stack はクロスプラットフォームの Haskell のビルドツールです
Haskell のコンパイラである GHC のダウンロードも stack がやってくれます

macOS の場合は brew を使ってbrew install haskell-stackでインストールできます
(他の OS や方法は公式を参照)

プロジェクトの作成

インストールしたらプロジェクトを作成します

stack new my-project
cd my-project
stack setup # 必要に応じて Haskell のコンパイラである GHC をダウンロードします

ここまででビルド、プログラムの実行ができるようになっています

stack build
stack exec my-project-exe
# stack 2.7.5 では someFunc と表示される

my-project-exeというのはstack newで作られるpackage.yamlで設定されている名前です

package.yaml
executables:
  my-project-exe: # ここの名前。このブロックを増やすことで実行コマンドを増やすことができる
    main:                Main.hs
    source-dirs:         app

ユニットテストの作成

今回は hspec でテストを作成してみました
hunit というものもあるようですがなんとなく hspec の方が情報量が多い気がしました

まずは依存関係を追加します

package.yaml
# 途中は省略しています
tests:
  my-project-test:
    dependencies:
    - hspec # これを追加

これでテストを書いて実行できるようになります

stack が初期化したテストのソースに追記する場合

test/Spec.hs
import Lib -- src/Lib.hs で hello 関数を export している場合
import Test.Hspec

main :: IO ()
main = hspec $ do
    describe "hoge" $ do
        it "fuga" $ do
            hello "world" `shouldBe` "hello world"

実行はstack testです

モジュール毎にテストを書く場合

開発を進めていくとモジュール毎にファイル/フォルダを分けていくと思いますが
そのような時はこのように書けます

例としてsrc/Lib.hsのテストをするtest/LibSpec.hsを作った場合

test/Spec.hs
import Test.Hspec
import qualified LibSpec

main = hspec spec

spec :: Spec
spec = do
    describe "LibSpec" LibSpec.spec -- 作ったモジュールのテストを実行
test/LibSpec.hs
module LibSpec where

import Test.Hspec
import Lib

spec :: Spec
spec = do
    describe "hello world" $ do
        it "return hello with name" $ do
            hello "world" `shouldBe` "hello world"

test/Spec.hsが テストスイートになるイメージです
ただし、この場合モジュールが増える度にtest/Spec.hsを更新する必要があります
hspec はこの部分が楽になるようにAutomatic spec discoveryという仕組みが準備されています

Automatic spec discovery を使う場合

test/Spec.hsをこのように書いておくと hspec が自動でテストを探して実行してくれるようになります

test/Spec.hs
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}

テスト実行の tips

その他、テスト実行について次のことを知っていると便利だと思いました

  • 更新を監視して自動でテスト実行したい
    • stack の--file-watchオプションをつける
    • 例:stack test --file-watch
  • 修正中のモジュールだけをテスト実行したい
    • stack の--test-argumentsオプション経由で hspec の--matchオプションをつける
    • 例:stack test --test-arguments "--match SomeLib"

感想

プロジェクト作成してとりあえず実行まではそんなに苦労しなかったですが
テスト作ってサードパーティのライブラリインストールしてとかまでやろうとすると
haskell 初心者には難しかったと思います
特に情報を探すのに他の言語と比べて苦労があったと思います

最近の言語であったり利用者が多い言語はそういうところが簡単になってたり
情報がすぐ見つかってありがたいですね
( go や python など)

参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?