10分で学ぶHaskell
From HaskellWiki
Contents |
1 概要
Haskellは関数型で(つまりすべてが関数呼びだしで処理される)、静的な暗黙的型付けで(型はコンパイラによって確認され、明示的に宣言する必要はない)、遅延評価(必要となるまで処理されない)の言語です。系統が近い言語として最も人気のあるのはおそらくML系の言語でしょう。(MLは遅延評価ではないですが)
最も普及しているHaskellのコンパイラは GHC です。GHCは http://www.haskell.org/ghc/download.html からダウンロードできます。GHCのバイナリは GNU/Linux、 FreeBSD、 MacOS、Windows、Solarisで動作します。GHCをインストールすると、ghcと ghciという2つのプログラムが入っているのが確認できます。最初のghcの方はHaskellのライブラリやアプリケーションをバイナリコードにコンパイルします。 ghciはインタプリタで、Haskellコードを書いてすぐに結果を得ることができる環境です。
2 簡潔な表現
たいていの数学的表現は直接ghciに入力して結果を得ることができます。Prelude>はGHCiのデフォルトのプロンプトです。
Prelude>15Prelude>
15Prelude>
16文字列は"ダブルクォート(二重引用符)"で囲みます。文字列の結合をするときは
"Hello"Prelude>
"Hello, Haskell"
関数を呼び出すときは関数の後に直接引数を並べて行います。関数呼び出しに括弧は必要ありません。こんな感じです:
Prelude>6Prelude>
6Prelude>
7Prelude>
1.4142135623730951Prelude>
TruePrelude>
7
3 コンソール
I/Oアクションはコンソールからの入出力を行うのに使います。有名なものの例は:
Prelude>Hello, HaskellPrelude>
9Prelude>
True
2 + 2 = 4Prelude>
ABCDE 12345読み込みは
4 16
(4が入力で16が結果です。)
実際にはmain = do putStrLn "What is 2 + 2?" x <- readLn if x == 4 then putStrLn "You're right!" else putStrLn "You're wrong!"
(Note: レイアウトを使う場合はインデントにタブを用いないでください。技術的にはタブが8文字であれば動作しますが、おすすめできません。また中にはそういう人もいるかもしれませんが、プロポーショナルフォントを使うこともおすすめしません。
4 簡潔な型
これまで、型宣言に関して全く触れてきませんでした。その必要がなかったのですが、それはHaskellが型推論を行うからです。一般的に型宣言はしたい場合以外はする必要がありません。型宣言をする場合は5Prelude>
5.0
Haskellでは型 (そして後で触れる型class)は常に大文字から開始します。変数は常に小文字から始まります。これは言語仕様であり、命名規則(naming convention)ではありません。
ghciを使って、ある値がどんな型かを確認することもできます。普段、自分では型宣言をしないので、この機能は役に立ちます。
Prelude> :t数字に関してはもっと面白いものが見られます。
Prelude> :tこれらの型は"型クラス"を用いています。つまり:
- はあらゆる数字型として使うことができます。(このおかげで42を5としてもIntとしても宣言できたわけです)Double
- はどのような分数型にもなれますが、整数型にはなれません。42.0
- (ちなみにこれは関数呼び出しです)はどのような整数型にもなれますが、分数型にはなれません。gcd 15 20
Haskellの"prelude"(初期状態でimportされるライブラリの一部)内には5種類の数値型があります。
- は少なくとも30ビットの精度の整数ですInt
- は精度無制限の整数型ですInteger
- は単精度浮動小数点数ですFloat
- は倍精度の浮動小数点数ですDouble
- は分数型で丸め誤差がありませんRational
ごちゃまぜにしてみましょう。
Prelude>7Prelude>
<interactive>:1:0:
No instance for (Integral Double)
最後に触れておいたほうがよい型は 5 構造化されたデータ
基本データ型は2つの方法で容易にまとめることができます。一つはリストで [ かぎ括弧 ] で囲います。もう一つはタプルで ( 括弧 ) で囲みます。
リストは同じ型の複数の値を保持する場合に使われます。
Prelude>[1,2,3]Prelude>
[1,2,3,4,5]Prelude>
[1,3,5,7,9]Prelude>
[True,False,True]
文字列は単に文字のリストにすぎません。
Prelude>"Hello"
"CHello"
タプルは決まった数の値を保持できます。ただしそれぞれの型は異なっていても構いません。
Prelude>(1,True)Prelude>
[(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')]この例の最後で
型は予想どおり以下のようになります。
Prelude> :tリストはHaskellではとてもよく使われます。リストを操作する便利な関数がいくつもあります。
Prelude>また整列されたペア(2つの要素を持つタプル)に対する便利な関数が2つあります。
Prelude>how to work on listsも参照してください。
6 関数定義
main = do putStrLn "What is 2 + 2?" x <- readLn if x == 4 then putStrLn "You're right!" else putStrLn "You're wrong!"
module Main where factorial n = if n == 0 then 1 else n * factorial (n - 1) main = do putStrLn "What is 5! ?" x <- readLn if x == factorial 5 then putStrLn "You're right!" else putStrLn "You're wrong!"
ghc --make Test.hsと入力し再ビルドします。そして実行します。
$ ./Test What is 5! ? 120 You're right!階数が得られました。ビルトイン関数のように、
今度はghciを使って型を調べてみましょう。
$ ghci Test.hs << GHCi banner >> Ok, modules loaded: Main.Prelude Main> :t
階数は場合分けを使うことで簡単にできます。
factorial 0 = 1 factorial n = n * factorial (n - 1)
7 便利な構文
さらにいくつかのsyntaxが便利です。
secsToWeeks secs = let perMinute = 60 perHour = 60 * perMinute perDay = 24 * perHour perWeek = 7 * perDay in secs / perWeek
classify age = case age of 0 -> "newborn" 1 -> "infant" 2 -> "toddler" _ -> "senior citizen"
8 ライブラリを使う
ここまでのチュートリアルではPreludeの一部しか使ってきませんでした。PreludeはHaskellのどんなプログラムでも使うことができる関数のセットです。
ここから生産性の高いHaskellプログラマになるためには、あなたが必要とするPrelude以外の librariesについて明るくなるのがよいです。標準ライブラリに関してはhttp://haskell.org/ghc/docs/latest/html/libraries/にあります。モジュールは以下のものがあります。
- Useful data structures
- Concurrent and parallel programming
- Graphics and GUI libraries
- Networking, POSIX, and other system-level stuff
- Two test frameworks, QuickCheck and HUnit
- Regular expressions and predictive parsers
- More...
module Main where import qualified Data.Map as M errorsPerLine = M.fromList [ ("Chris", 472), ("Don", 100), ("Simon", -5) ] main = do putStrLn "Who are you?" name <- getLine case M.lookup name errorsPerLine of Nothing -> putStrLn "I don't know you" Just n -> do putStr "Errors per line: " print n
もし標準ライブラリにないものを必要とする場合は、 http://hackage.haskell.org/packages/hackage.html かこのWikiのapplications and librariesのページを見てください。これらは多くの方々がHaskellのために書いたたくさんのライブラリを集めたページです。ライブラリを手元に落としてきたら、展開してそのディレクトリに入って以下を実行してください:
runhaskell Setup configure runhaskell Setup build runhaskell Setup install
UNIXでは最後のrunhaskell Setup installを実行するためにrootになる必要があります。
9 10分以上かかるので省いたトピック
- Advanced data types
- Advanced syntax
- 発展的な関数
- Monads
- File I/O
- ファイルの読み込み
- ファイルの書き込み
