みずりゅの自由帳

主に参加したイベントやソフトウェア技術/開発について記録しています

HaskellのGHCiする時のメモ

備忘録。

昨年購入して途中まで読んでいたHaskell本(プログラミングHaskell 第2版)を、気が向いて読み直している。

プログラミングHaskell 第2版(紙書籍+電子書籍)www.lambdanote.com

ここで、GHCiの起動方法や、GHCi内で複数行入力のやり方を忘れていたので、思い出せるようにメモしておく。

GHCiの起動

直接インストールはせずに、Haskellの公式Dockerを利用した。 Dockerイメージの詳細はこちら。 hub.docker.com

以下、2020年4月15日時点での最新バージョン「8.8.3」を利用する例。

docker run --rm -it haskell:8.8.3

こちらの場合は、GHCiがすぐに起動する。

GHCi, version 8.8.3: https://www.haskell.org/ghc/  :? for help
Prelude>

続いて、ディレクトリをマウントしてHaskellファイルを読み込んだり、コンテナ内で操作したい場合。

docker run --rm -it -v $PWD:/tmp haskell:8.8.3 /bin/bash

ひとまずカレントディレクトリを/tmpにマウントしているが、必要に応じてマウント先は変更すれば良い。

実行すれば、コンテナ内に入る。 なお、利用したコンテナのOSは「debian:stretch」である。

そして、コンテナ内ではghciコマンドを実行できる。

root@00b32a459b44:/# ghci
GHCi, version 8.8.3: https://www.haskell.org/ghc/  :? for help
Prelude>

例では、「/tmp」下(正確には、マウントしているカレントディレクトリ)にソースファイル(test.hs)を置いてあるので、そのファイルをGHCiで読み込ませる。

root@00b32a459b44:/#
root@00b32a459b44:/# ls /tmp
memo.txt  test.hs
root@00b32a459b44:/# cat /tmp/test.hs
double x = x + x
quadruple x = double (double x)
root@00b32a459b44:/# ghci /tmp/test.hs
GHCi, version 8.8.3: https://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( /tmp/test.hs, interpreted )
Ok, one module loaded.
*Main> double 9
18
*Main> quadruple 9
36
*Main>

GHCi内で複数行を入力する

:{:}で囲む。ただし、それぞれ、独立した行で記述する。

以下、記述例。

Prelude> :{
Prelude| n = a `div` length xs
Prelude|     where
Prelude|         a = 10
Prelude|         xs = [1, 2, 3, 4, 5]
Prelude| :}

プレリュード関数の上書き

プレリュード関数(あらかじめ定義されている関数)を上書き(再定義)できる。 例えば、リストの最後を取得するプレリュード関数「last」を「head」のような動きにすることが簡単に出来てしまう。

あまりにも簡単に出来てしまったので、注意が必要だなぁと思った。

Prelude> last [1,3,5,7,9]
9
Prelude> head [1,3,5,7,9]
1
Prelude> last x = head x
Prelude> last [1,3,5,7,9]
1

なお、GHC 8.0.1 より前のバージョンでは「let」を利用しないと値や関数の束縛ができないらしい。