Stack を使って Haskell の Hello World をやってみる
以前 Stack を使って すごいH本 を学習したのですが、それっきり全く Haskell に触れていなかったのでリハビリがてら、 Stack を導入して Hello World を出力するまでの方法について書いておきます。
Stack のインストール
Mac の場合は Homebrew を使ってインストールできます。
brew install haskell-stack
プロジェクトの作成とビルド
公式の Quick Start Guide に書いてある通りにやりましょう。
Quick Start Guide — stack documentation
stack new my-project cd my-project stack setup stack build
Hello World!
次は、プロジェクトの中身を少し修正しておなじみの Hello World を出力してみましょう。
app/Main.hs
module Main where import Lib main :: IO () main = someFunc
app/Main.hs
がメインのパッケージです。
Hello World を出力するためには、この中の main
関数を修正すればよさそうですが、コードを見た限りだと main
は someFunc
という関数を指しているだけです。
someFunc
の実体は Lib
パッケージ内にあります。 import Lib
で Lib
パッケージをインポートしていてその関数を使っているわけです。
インポートされているパッケージはデフォルトでは src
以下に置かれているので見てみましょう。
src/Lib.hs
module Lib ( someFunc ) where someFunc :: IO () someFunc = putStrLn "someFunc"
src/Lib.hs
の最後の2行が someFunc
の実体になります。 someFunc = putStrLn "someFunc"
を someFunc = putStrLn "Hello World"
という風に修正します。
そして stack runghc
で main
関数を実行できます。
( stack exec my-project-exe
でも同様の結果が得られます)
$ stack runghc app/Main.hs Hello World
以上です。簡単でしたね。
おまけ
先ほど実行した app/Main.hs
、実は stack ghci
でも実行できます。
$ stack ghci The following GHC options are incompatible with GHCi and have not been passed to it: -threaded Using main module: 1. Package 'my-project' component exe:my-project-exe with main-is file: /my-project/app/Main.hs Configuring GHCi with the following packages: my-project GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Lib ( /my-project/src/Lib.hs, interpreted ) Ok, modules loaded: Lib. [2 of 2] Compiling Main ( /my-project/app/Main.hs, interpreted ) Ok, modules loaded: Lib, Main. *Main Lib> main Hello World
GHCi はすごいH本を学習している方はおなじみですね。
なので、これから Stack を使ってすごいH本を学習しようと考えている人は、
- 作成したパッケージは
src
以下に置く stack ghci
で GHCi を起動した状態で、パッケージをロードして関数を実行するmain
関数のような I/O アクションを実行する場合は、stack runghc src/MyPackage.hs
を使う
というスタイルがよいかもしれません(自分はこうやって学習していました)。
例えば src/Baby.hs
内の doubleMe
という関数が使いたい場合は、次のように :l
でパッケージのロードをすることで使えるようになります。
$ stack ghci ... *Main Lib> :l src/Baby.hs [1 of 1] Compiling Main ( src/Baby.hs, interpreted ) Ok, modules loaded: Main. *Main> doubleMe 9 18