初速1PV

プログラミングにまつわることの記録

StackでHaskellのプロジェクトをビルドする

StackでHaskellのプロジェクトの生成、ビルドをします。 メモです。

Hello world

プロジェクトを作らず、stack経由でghcを呼び出してビルドしてみる。 Main.hsという名前でHello worldするプログラムを保存する。

module Main where

main :: IO ()
main = putStrLn "Hello from Haskell!"

ghc, runghcが動くことを確認する。

$ stack exec -- ghc Main.hs
$ ./Main
Hello from Haskell!
$ stack exec -- runghc Main.hs
Hello from Haskell!

プロジェクトの作成

第三引数であるtemplateをなしにするとデフォルトのプロジェクトを作成する。

stack new my-project

例えばrioyesodweb/sqliteがtemplateとしてある。

stack new my-project rio

ビルド

プロジェクトのビルド

プロジェクトを作成したばかりなら最初にsetupする。 setupによりプロジェクトに適したバ一ジョンのGHCを入れることができる。

stack setup

`stack buildでビルドを開始する。

stack build

オプション

stack build --helpに色々と載っている。 - stack build --file-watch - ファイルが編集されていれば自動で再コンパイルしてくれる - stack build --fast - -O0コンパイルする。

stack build --fast --file-watchとすると-O0で勝手に再コンパイルしてくれるようになる。

実行例

stack new rio-test rio
<省略>...
cd rio-test
ls
app  ChangeLog.md  LICENSE  package.yaml  README.md  rio-test.cabal  Setup.hs  src  stack.yaml  test
stack build
<省略>...
stack run
We're inside the application!

stack runで実行可能なアプリケ一ションの1つめを実行することができる。 上記の例ではapp/Main.hsから出来たプログラムが実行されている。grepか何かで出力元を探すとsrc/Run.hsが実行されているがapp/Main.hsはそのRun.hs内のrunRIOを呼び出している。なので、適当にデバッグ出力をapp/Main.hsに挿入するとそこもうまく評価されていることを確認できる。 下記のコ一ドは既存のapp/Main.hsBangPatternsを使ってDebug.Trace.traceを正格評価させた処理を追加したもの。

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE BangPatterns #-}
module Main (main) where

import Import
import Run
import RIO.Process
import Options.Applicative.Simple
import qualified Paths_test2
import Debug.Trace

main :: IO ()
main = do
  (options, ()) <- simpleOptions
    $(simpleVersion Paths_test2.version)
    "Header for command line arguments"
    "Program description, also for command line arguments"
    (Options
       <$> switch ( long "verbose"
                 <> short 'v'
                 <> help "Verbose output?"
                  )
    )
    empty
  lo <- logOptionsHandle stderr (optionsVerbose options)
  pc <- mkDefaultProcessContext
  withLogFunc lo $ \lf ->
    let !_ = Debug.Trace.trace "Test" () in
    let app = App
          { appLogFunc = lf
          , appProcessContext = pc
          , appOptions = options
          }
     in runRIO app run

実行結果

stack run
Test
We're inside the application!

その他

stack execでサンドボックス下でコマンドを実行できる

stack exec -- <command>

自分の環境では

ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.0.2
stack exec -- ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.4

となっていたのでstackによってHaskellの環境が変わることがわかる。 stack exec -- <command><command>は何でもよくてstack exec -- bashするとstackの上でシェルを起動てきたりする。この状態でのghcはstackに影響される。

ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.4

さいごに

今回はstack newでデフォルトのプロジェクトを生成したりテンプレ一トからプロジェクトを作ってstack runを実行してみました。 参考の章にあるリンクにかなり詳しく書いてのでおすすめです。

参考