HaskellコンパイラであるGHC (Glasgow Haskell Compiler)のインタラクティブ対話型シェルのGHCiの主要なコマンドについて紹介します。
Contents
GHCi
Haskellのコンパイラで広く利用されているものはGHC (Glasgow Haskell Compiler)です。GHCには、インタラクティブな対話型シェルであるGHCiがあります。
GHCiを使うことでモジュール分割されたファイルの関数を個別に動作確認するといったことも可能となるため非常に便利です。Haskellでは、GHCiで各モジュールの関数を動作確認し、確認が終わったらGHCでコンパイルするという開発の流れが一般的です。
GHCiには様々なコマンドがありますが、主要なコマンドを把握しておくことは非常に役立ちます。本記事では、GHCiの主要なコマンドを紹介します。
GHCiの主要なコマンド
以降では、GHCiにおける主要なコマンドを紹介していきます。実行例で表示している「$」「ghci>」の部分については端末への入力を意味します。
GHCiを終了する (:q
)
対話型インターフェースを使う場合にまず覚えないといけないことは、GHCiの終了方法です。GHCiを終了するには「:q
」コマンドを使用します。
$ ghci
ghci> :q
Leaving GHCi.
ヘルプを表示する (:?
または :help
)
GHCiで使用できコマンドを表示する場合には「:?
」または「:help
」コマンドを使用します。
$ ghci
ghci> :?
Commands available from the prompt:
<statement> evaluate/run <statement>
: repeat last command
:{\n ..lines.. \n:}\n multiline command
:add [*]<module> ... add module(s) to the current target set
:browse[!] [[*]<mod>] display the names defined by module <mod>
(!: more details; *: all top-level names)
:cd <dir> change directory to <dir>
(...省略...)
ファイルをロードする(:l
または :load
)
以下のようなtest.hsというプログラムがあるとします。このファイルをGHCiで読み込んで関数を実行する場合を例にファイルをロードする方法を説明します。
-- Test用Haskellプログラム
-- main関数を開始
main :: IO ()
main = do
-- テスト出力
print "Hello World!"
GHCiでHaskellプログラムを読み込む場合には、以下のように読み込むことができます。読み込んだ後でmain関数などのプログラム中の関数を呼び出して実行することが可能です。
$ ghci test.hs
[1 of 2] Compiling Main ( test.hs, interpreted )
Ok, one module loaded.
ghci> main
"Hello World!"
GHCiを立ち上げた状態でHaskellプログラムを読み込む場合には「:l
」または「:load
」コマンドを使用します。
$ ghci
ghci> :l test.hs
[1 of 2] Compiling Main ( test.hs, interpreted )
Ok, one module loaded.
ghci> main
"Hello World!"
型を表示する (:t
または :type
)
Haskellでは、強力な型システムが特徴的な関数型プログラミング言語です。そのため、型の情報を調べて正確に把握することは非常に重要になります。GHCiで、型を調べる際には「:t
」または「:type
」コマンドを使用します。
式の型を表示する
Haskellでは、単一の値、例えば数値や文字列、またはより複雑な関数の呼び出しなど、評価されるあらゆるものを式(expression)と呼びます。以下のように、Haskellでの式の型を確認することができます。
$ ghci
ghci> :t 10
10 :: Num a => a
上記では、数値10
がNum
型クラスの任意のインスタンスa
であることを示しています。これは、10
が整数(Int
)や倍精度浮動小数点数(Double
)等のその他 Num
型クラスのインスタンスである任意の数値型であることを意味します。
この型シグネチャは、10
が特定の型に限定されていないことを示していて、Haskellの型推論システムがその文脈に応じて適切な具体的な型を選択できるようにします。
関数の型を表示する
関数の型を表示する場合には、以下のように確認することができます。以下は、reverse
関数の型を確認してみた例です。
$ ghci
ghci> :t reverse
reverse :: [a] -> [a]
reverse :: [a] -> [a]
は、Haskellの型シグネチャで、reverse
関数が任意の型a
のリスト([a]
)を受け取り、同じ型の要素を持つ新しいリストを返すことを意味しています。
この型シグネチャは、reverse
関数が型に依存しない汎用関数であることを示しており、任意の型のリストに適用できることを意味しています。
型がどの型クラスのインスタンスかを表示する (:instances
)
Haskellでは、型クラスのインスタンスとなっている型があります。型がどの型クラスのインスタンスとなっているかを確認したい場合には、「:instances
」コマンドを使用します。
$ ghci
ghci> :instances Int
instance Bounded Int -- Defined in ‘GHC.Enum’
instance Read Int -- Defined in ‘GHC.Read’
instance Enum Int -- Defined in ‘GHC.Enum’
instance Integral Int -- Defined in ‘GHC.Real’
instance Num Int -- Defined in ‘GHC.Num’
instance Real Int -- Defined in ‘GHC.Real’
instance Show Int -- Defined in ‘GHC.Show’
instance Eq Int -- Defined in ‘GHC.Classes’
instance Ord Int -- Defined in ‘GHC.Classes’
上記例では、Int
型は、Bounded
、Read
、Enum
、Integral
、Num
、Real
、Show
、Eq
、Ord
といった型クラスのインスタンスとなっていることを示しています。
このようにどの型クラスのインスタンスかを確認することで、その型が有する特徴を把握することができるようになります。
情報を表示する (:info
)
指定した識別子(変数、関数、型、型クラス等)に関する詳細情報を確認したい場合には、「:info
」コマンドを使用します。以下では、いくつかの例を用いて紹介します。
以下結果を見てもらうと分かりますが:info
コマンドは、:type
や:instances
を包含したような情報を提供してくれます。
変数の情報
変数の情報は、以下のように確認できます。
$ ghci
ghci> let x = 10
ghci> :info x
x :: Num a => a -- Defined at <interactive>:1:5
上記例では、GHCi上で定義したx
について情報を表示しています。x
は、Num
型クラスの任意のインスタンスa
であることを示しています。また、定義されている場所に関する情報も付与されています。
関数の情報
関数の情報は、以下のように確認できます。以下は、reverse
関数の情報を確認してみた例です。
$ ghci
ghci> :info reverse
reverse :: [a] -> [a] -- Defined in ‘GHC.List’
結果としては、:type
コマンドでの結果と似ていますが、リストの定義情報が提示されているなど追加の情報が表示されています。:type
コマンドが型の情報を表示するのに対して、:info
コマンドはより詳細な情報を表示します。
型の情報
型の情報は、以下のように確認できます。以下は、Maybe
型の情報を確認してみた例です。
$ ghci
ghci> :info Maybe
type Maybe :: * -> *
data Maybe a = Nothing | Just a
-- Defined in ‘GHC.Maybe’
instance Semigroup a => Monoid (Maybe a) -- Defined in ‘GHC.Base’
instance Semigroup a => Semigroup (Maybe a)
-- Defined in ‘GHC.Base’
instance Foldable Maybe -- Defined in ‘Data.Foldable’
instance Traversable Maybe -- Defined in ‘Data.Traversable’
instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
instance Applicative Maybe -- Defined in ‘GHC.Base’
instance Functor Maybe -- Defined in ‘GHC.Base’
instance MonadFail Maybe -- Defined in ‘Control.Monad.Fail’
instance Monad Maybe -- Defined in ‘GHC.Base’
instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Maybe’
instance Ord a => Ord (Maybe a) -- Defined in ‘GHC.Maybe’
上記では、Maybe
の定義情報や、Maybe
がどの型クラスのインスタンスかの情報を提供してくれます。
型クラスの情報
型クラスの情報は、以下のように確認できます。以下は、Monad
型クラスの情報を確認してみた例です。
$ ghci
ghci> :info Monad
type Monad :: (* -> *) -> Constraint
class Applicative m => Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
{-# MINIMAL (>>=) #-}
-- Defined in ‘GHC.Base’
instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’
instance (Monoid a, Monoid b) => Monad ((,,) a b)
-- Defined in ‘GHC.Base’
instance (Monoid a, Monoid b, Monoid c) => Monad ((,,,) a b c)
-- Defined in ‘GHC.Base’
instance Monad ((->) r) -- Defined in ‘GHC.Base’
instance Monad IO -- Defined in ‘GHC.Base’
instance Monad Maybe -- Defined in ‘GHC.Base’
instance Monad Solo -- Defined in ‘GHC.Base’
instance Monad [] -- Defined in ‘GHC.Base’
instance Monad (Either e) -- Defined in ‘Data.Either’
上記では、Monad
のクラス定義情報や、Monad
がどの型クラスのインスタンスかの情報を提供してくれます。
型コンストラクタのカインドを表示する (:kind
)
Haskellにおいて型コンストラクタとは、型を生成するためのもので他の型を引数として取ることができます。カインドとは、型コンストラクタが取ることのできる型引数を表すもので、型の「型」のようなものです。
GHCiの「:kind
」コマンドを使用することで調べることができます。
単純な型コンストラクタ
単純な型で型コンストラクタを調べてみます。以下は、Int
のカインドを調べる例です。
$ ghci
ghci> :kind Int
Int :: *
Int
のような具体的な型がカインド「*
」であることは、追加の型引数を取らないことを意味しています。
引数がある型コンストラクタ (引数が1つ)
引数がありパラメータ化されている方として代表的なものとしては、Maybe
型があります。以下は、Maybe型のカインドを調べる例です。
$ ghci
ghci> :kind Maybe
Maybe :: * -> *
Maybeのような引数を1つ取る型のカインドは「* -> *
」というようになります。Maybe
では、Maybe Int
といった表記を見たことがあると思いますが、これはMaybe
がInt
を引数に取っていることを意味します。
Maybe
は欠損値に対応するために、値が存在するかもしれないことを表現するものであるため、Maybe Int
は、Int
が存在するかもしれないし、存在しないかもしれないということを表現します。
複数の引数がある型コンストラクタ (引数が2つ)
複数の引数を受け取る方もあり、代表的なものとしては、Either
型があります。以下は、Either
型のカインドを調べる例です。
$ ghci
ghci> :kind Either
Either :: * -> * -> *
Either
のような引数を2つ取る型のカインドは「* -> * -> *
」というようになります。Either
では、Either String Int
といった表記を見たことがあると思いますが、これはEither
がString
とInt
を引数に取っていることを意味します。
Either
は、2つの異なる型の値のいずれかを含むことを表現するものであるため、Either String Int
は、String
かInt
のいずれかということになります。例えば、エラー処理においてエラー文字列を返すか、成功した値を返すような場合に使用します。
まとめ
HaskellコンパイラであるGHC (Glasgow Haskell Compiler)のインタラクティブ対話型シェルのGHCiの主要なコマンドについて紹介しました。
本記事では、よく使うであろう代表的なコマンドについて紹介しています。Haskellでは、GHCiで各モジュールの関数を動作確認し、確認が終わったらGHCでコンパイルするという開発の流れが一般的です。
GHCiには様々なコマンドがありますが、主要なコマンドを把握しておくことは非常に役立ちますので参考にしてもらえればと思います。