YAMAGUCHI::weblog

土足で窓から失礼いたします。今日からあなたの息子になります。 当年とって92歳、下町の発明王、エジソンです。

GHCiを使って学ぶ (はじめて編)

はじめに

あけましておめでとうございます。正月休みを使って手探りでHaskellの学び方を模索しているわけですが、「これは便利だ!」と思ったので自分へのメモと同時に、共有です。もっと便利な方法を教えてください!

Haskellの対話型実行環境GHCi

Haskellの実装は幾つかありますが、コンパイラと対話型実行環境があります。対話型実行環境を使うと、Haskellのコードをコンパイルせずに*1コードのテストができるのでとても便利です。対話型実行環境としてメジャーなのはGHCiかHugsだと思います。自分のHaskell開発環境ではコンパイラにGHCを選択したので前者のGHCiを使うことにしました。
このGHCiを最近まともに使い始めたわけですが、なかなかこれが優れものだったので自分の使い方を紹介します。

実装中のソースをテストしながら動かす

GHCiではMainモジュール内でmainメソッドを実装しておけば :load で読み込むことができます。

$ ghci
GHCi, version 6.10.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l hoge    # hoge.hsを読み込む。:l は :load の省略形。
[1 of 1] Compiling Main             ( hoge.hs, interpreted )
Ok, modules loaded: Main.
*Main>

なお、GHCiではコマンド名の頭文字が一意になっているので、省略形としてコマンド名の最初の1文字を使うことができます。

型とかを確認する

コードを書きながらモジュール内の関数の型を確認したりしたいときがあります。そういうときは :browse を使ってごっそり確認します。

*Main> :browse Text.ParserCombinators.Parsec
(<?>) :: GenParser tok st a -> String -> GenParser tok st a
(<|>) ::
  GenParser tok st a -> GenParser tok st a -> GenParser tok st a
type CharParser st a = GenParser Char st a
type Column = Int
(略)
tokens ::
  (Eq tok) =>
  ([tok] -> String)
  -> (SourcePos -> [tok] -> SourcePos)
  -> [tok]
  -> GenParser tok st [tok]
try :: GenParser tok st a -> GenParser tok st a
unexpected :: String -> GenParser tok st a
updateState :: (st -> st) -> GenParser tok st ()
upper :: CharParser st Char

こうやっていろいろ確認できます。他人が書いたコードとかで型がソースに書いてないときは :type や :info を使います。

*Main> :t parseInput
parseInput :: GenParser Char st [Dir]
*Main> :i parseInput
parseInput :: GenParser Char st [Dir]
       -- Defined at hoge.hs:5:0-9

上記では両方とも省略系を使っています。infoの場合、型だけでなくどのモジュール内にあるか、どのソースにあるかというところまで見られます。

これから

GHCiを使うとデバッガなんかも内蔵しちゃっているのでさらに便利に使えるんじゃないかと思っています。ちょっとGHCiの使い方まとまってるサイト探してみようかなあ。

*1:実際は環境内でコンパイルしているけれど