PROGRAMMING IN HASKELL
Chapter 1 - Introduction
愛知県立大学 情報科学部 計算機言語論(山本晋一郎・大久保弘崇、2011年)講義資料。
オリジナルはhttp://www.cs.nott.ac.uk/~gmh/book.htmlを参照のこと。
0
はじめに
 教科書
プログラミングHaskell
Graham Hutton (著), 山本 和彦 (翻訳)
オーム社、232ページ
 成績: 試験とレポートを総合的に評価
1
参考 URL
 計算機言語論
http://www.ist.aichi-pu.ac.jp/lab/yamamoto/program_languages
 訳者によるサポートページ(正誤表など)
http://www.mew.org/~kazu/doc/book/haskell.html
 著者によるサポートページ(正誤表、英語版スライドな
ど)
http://www.cs.nott.ac.uk/~gmh/book.html
 Haskellに関する包括的な情報源
http://www.haskell.org/
2
(Intro) それはどんな言語だ!?
 What‘s faster than C++, more concise than Perl,
more regular than Python, more flexible than
Ruby, more typeful than C#, more robust than
Java, and has absolutely nothing in common with
PHP? It's Haskell!
 C++よりも高速で、Perlよりも簡潔で、Pythonよりも例
外が少なく、Rubyよりも柔軟で、C#よりも型付いてい
て、Javaよりも頑丈で、PHPとは似ても似つかない言
語は? それは Haskell!
3
(Intro) 関数型プログラミング言語とは!?
 全てが関数(全てが式と言い換えても良い)
 式は定数,変数,関数呼び出し(1引数以上)から成る
 定数は一定の値を返す 0 引数の関数
 変数の値を変更できない (1 回だけ代入、何度参照しても同じ値)
 計算はそれらの値を求めること
 C 言語も(全てが)関数で構成されている
 本当?
 if 文,for 文,ブロックは式ではない(値を持たない)
 関数を値にできない(ポインタ!?)
 プログラムの実行中に新しい関数を作れない
4
ソフトウェア危機(The Software Crisis)
 プログラムの規模と複雑さにどのように対処すべき
か?
 プログラム開発の期間とコストを削減する方法は?
 開発したプログラムが正しく動作するという確信をど
のようにしたら持てるのか?
5
Programming Languages
次のような性質を備えた新しいプログラミング言語
によりソフトウェア危機に対処:
 明確、簡潔、高い抽象度のプログラミングが可能
 ソフトウェア部品の再利用が支援されている
 形式的検証(formal verification)が容易
6
 ラピッドプロトタイピング(rapid prototyping)が容易
 問題解決の強力なツールとなり得る
関数型言語(functional languages)はこれらの目標を
達成するためのエレガントな枠組み
7
関数型(プログラミング)言語とは?
さまざまな見解があり、正確に定義することは難しい
が、一般論としては:
 関数プログラミングとは、「関数を引数へ適用するこ
と」を計算原理とするプログラミングの流儀(style)
 関数型言語とは、関数プログラミングの流儀を支援
(support)し奨励(encourage)するプログラミング言
語
8
Example
1 から 10 を足し合わせる Java/C プログラム:
total = 0;
for (i = 1; i  10; i++) {
total = total + i;
}
計算原理は変数への代入(variable assignment)
・蓄えられている値が変化していく
・人は変化を追跡することが苦手
9
Example
1 から 10 を足し合わせる Haskell プログラム:
sum [1..10]
計算原理は関数を引数に適用すること
(function application)
[1..10] は整数のリスト [1, 2, 3, …, 10] を生成し、
sum はリストの要素の総和を求める
10
Historical Background
1930s:
Alonzo Church が単純だけど強力な関数の理論
である  算法(lambda calculus)を開発
11
Historical Background
1950s:
John McCarthy が、最初の関数型言語である Lisp
を開発。 算法に影響を受けているが、計算原理と
して変数代入を採用していた。
12
Historical Background
1960s:
Peter Landin が世界初の純粋な関数型言語で
ある ISWIM を開発。  算法に強く基礎を置い
ており、変数代入を排除した。
13
Historical Background
1970s:
John Backus が関数型言語 FP を開発。高
階関数とプログラミングの論証に重点を置
いた言語である。
14
Historical Background
1970s:
Robin Milner らが最初の現代的な関数型言語で
ある ML を開発。型推論と多相型を導入した。
15
Historical Background
1970s - 1980s:
David Turner が遅延評価(lazy evaluation)をもつ関
数型言語の開発を進めた(Mirandaとして結実)
lazyはほめ言葉!
16
Historical Background
1987:
lazy な関数型言語が乱立したので、標準
(Haskell)を設定する委員会が発足
17
Historical Background
2003:
委員会が Haskell 98 Report を公開し, 安定版の
言語仕様を定めた(Haskell 2010 へ発展)
18
Haskellはこんな感じ(リスト)
要素は全て同じ型
[1, ’a’] は許されない
[]
空のリスト(長さ0)
[10]
長さ1のリスト(要素は10)
[10, 20]
長さ2のリスト(先頭要素は10, 2番目は20)
[10, 20, 30]
x:xs
長さ3のリスト
空でないリスト(長さ1以上)
x 先頭要素、 xs 先頭要素を除いたリスト
1:[]
= [1]
1:2:[]
= 1:[2] = [1, 2]
1:2:3:[]
= 1:2:[3] = 1:[2, 3] = [1, 2, 3]
19
リストの復習(Cons演算子)
 [1] = 1 : [ ]
:
1
[]
 [1, 2] = 1 : (2 : [ ])
:
1
:
2
[]
 [1, 2, 3] = 1 : (2 : (3 : [ ]))
:
:
1
2
:
3
[]
20
Haskellはこんな感じ(リスト)
++
リストの連結
[] ++ [1, 2, 3] = [1, 2, 3]
[1, 2, 3] ++ [] = [1, 2, 3]
[1, 2, 3] ++ [4, 5] = [1, 2, 3, 4, 5]
[1, 2] ++ [] ++ [3, 4] = [1, 2, 3, 4]
head
リストの先頭要素
head [1, 2, 3] = 1
tail
リストの先頭要素を除いたリスト
tail [1, 2, 3] = [2, 3]
21
Haskellはこんな感じ(数値リストの総和)
sum []
= 0
sum (x:xs) = x + sum xs
sum [1, 2, 3]
= 1 + sum [2, 3]
= 1 + (2 + sum [3])
= 1 + (2 + (3 + sum []))
= 1 + (2 + (3 + 0))
= 6
22
Haskellはこんな感じ(フィボナッチ数列)
fib
= 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]
zip は 2 つのリストの要素を互いにペアにしたリストを返す
zip [1, 2, 3] [10, 20, 30] = [(1,10), (2,20), (3,30)]
23
Haskellはこんな感じ
f []
= []
f (x:xs) = f smaller ++ [x] ++ f larger
where
smaller = [a | a  xs, a  x]
larger = [b | b  xs, b > x]
?
24
Haskellはこんな感じ
f []
= []
f (x:xs) = (f smaller) ++ [x] ++ (f larger)
ただし
smaller = [a | a  xs, a  x]
larger = [b | b  xs, b > x]
25
Haskellはこんな感じ(クイックソート)
f []
他のプログラミ
ング言語と比べ
て簡潔
= []
f (x:xs) = (f smaller) ++ [x] ++ (f larger)
ただし
smaller = [a | a  xs, a  x]
larger = [b | b  xs, b > x]
 空リストはソート済み
 非空リストのソートは以下の 3 つのリストの連結
 (残りのリストで先頭要素以下の要素)をソートしたリスト
 先頭要素のみのリスト
 (残りのリストで先頭要素より大きな要素)をソートしたリスト
26
例 (qsort を q と省略):
q [3,2,4,1,5]
q [2,1] ++ [3] ++ q [4,5]
q [1] ++ [2] ++ q []
[1]
[]
q [] ++ [4] ++ q [5]
[]
[5]
27
([1] ++ [2] ++ []) ++ [3] ++ ([] ++ [4] ++ [5])
GHC (Haskell Platform)
 GHC は広く使われている Haskell 98 の実装
 ghc はコンパイラ、ghciはインタプリタ
 ghci の対話性は教育とプロトタイピングに適している
 Haskell Platform は,GHC にライブラリやツールなど
を加えた環境一式を提供
 Windows, Mac, Linux版
 以下のサイトからダウンロードできる
http://hackage.haskell.org/platform/
教科書では Hugs を使っているが、Hugs と GHC の差異は
小さいので、広く用いられている GHC (ghci)を用いれば良い
28
Haskell Platform のインストール (1/4)
 Windows へのインストール方法
1.
2.
3.
4.
http://hackage.haskell.org/platform/windows.html へアクセスする
[Download Haskell for Windows] をクリックし、
[HaskellPlatform-2011.2.0.1-setup.exe] を保存する
保存した [HaskellPlatform-2011.2.0.1-setup.exe] を実行する
[Next] を押す
29
Haskell Platform のインストール (2/4)
 Windows へのインストール方法
5.
インストールの場所を選択し,[Next] をクリックする
30
Haskell Platform のインストール (3/4)
 Windows へのインストール方法
6.
インストールのタイプは [Standard] を選択し、[Next] をクリックする
31
Haskell Platform のインストール (4/4)
 Windows へのインストール方法
7.
[Install] をクリックするとインストールが実行される
32
Starting Hugs
 UNIX では、シェルプロンプトから hugs (ghci) を起動する
 Windows では、スタートメニュの Haskell Platformから、
GHCi か WinGHCi を起動する
% hugs
__
__
||
||
||___||
||---||
||
||
||
||
__ __ ____
___
|| || || || ||__
||__|| ||__|| __||
___||
_________________________________________
Hugs 98: Based on the Haskell 98 standard
Copyright (c) 1994-2005
World Wide Web: http://haskell.org/hugs
Bugs: http://hackage.haskell.org/trac/hugs
Version: September 2006 _________________________________________
Haskell 98 mode: Restart with command line option -98 to enable extensions
Type :? for help
Hugs>
% ghci
GHCi, version 6.12.3: http://www.haskell.org/ghc/
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>
:? for help
33
ダウンロード

Click here to get the file