More Related Content Similar to Haskell Lecture 1 Similar to Haskell Lecture 1 (11) More from Yusuke Matsushita More from Yusuke Matsushita (11) Haskell Lecture 15. Pure ― 純粋関数型言語
• 純粋 ― 参照透過性が守られているということ。
• 参照透過性 ― すべての式は、いつ計算しても同
じ値をもつということ。
• 処理の実行されるタイミングを考えなくてよく
なる。とくに、並行処理が簡単になる。
• 仕様を書くような感覚でプログラミングできる。
純粋関数型言語 pure functional language
参照透過性 referential transparency
6. Lazy ― 遅延評価
• 遅延評価、くわしくいうと必要渡しを原則とし
ている。
• 必要渡し ― 式を、必要になったときだけ計算す
る。一度計算した値は、なるべく再利用する。
• 計算量を減らすことができる。とくに、高速に
再帰的な処理をすることができる。
遅延評価 lazy evaluation
必要渡し call by need
7. Useful ― 実用的
• 高速である。
• バグがすくない。
• 書きやすく、読みやすい。
• テスト駆動開発、 C言語との連携、デバッガ、
パッケージ管理などのための使いやすいツール
がそろっている。
• 急成長しているので、これからもっと使われて
いくはず。
8. Simple ― 簡潔
• 短く、明快で、管理しやすい。
• インデントや記号をうまく利用している。
• 抽象的な記述ができる。
• すっきりした、合理的な文法である。
• 中毒性があるくらいに、書きやすい。
10. Haskell Platform
• Haskell Platformを入れましょう。以上!
• GHC (コンパイラ), GHCi (インタープリタ),
Cabal (パッケージマネージャ), Haddock (文書
ジェネレータ), 便利なライブラリなどが入って
います。
16. 記号一覧
• [pattern] オプション
• {pattern} 0回以上の繰りかえし
• {pattern}+ 1回以上の繰りかえし
• (pattern) グループ化
• pattern1 | pattern2 選択
• pattern<pattern’> 差異
• ... 同様に繰りかえす
• [a..zA..Z] アルファベット一文字
22. module →
module modid where
body
| module modid (export1, ...) where
body
| body
modid → {modid’ .} modid’
modid’ → [A..Z] {[a..zA..Z0..9’]} 一文字目は大文字
module Main (main) where を省略したことになる
23. export →
qvar
| qtycon
| qtycon (..)
| qtycon (cname1, ...)
| qtycls
| qtycls (..)
| qtycls (qvar1, ...)
| module modid
型構築子のみ
型構築子・データ構築子・フィールドラベルのすべて
データ構築子とフィールドラベルを指定
型クラスのみ
型クラスとクラスメソッドのすべて
クラスメソッドを指定
24. body → {impdecl}{topdecl}
impdecl →
import modid [impspec]
| import modid as modid’ [impspec]
| import qualified modid [impspec]
| import qualified modid as modid’ [impspec]
impspec →
(import1, ...)
| hiding (import1, ...)
import →
var
| tycon [(..) | (cname1, ...)]
| tycls [(..) | (var1, ...)]
インポートするものを指定
インポートしないものを指定
qualifiedでプレフィックスを義務化
デフォルトではモジュール
名がプレフィックス
プレフィックス
を指定
27. 多相型
• パラメータ多相 ― 型を型引数によって全称量化
することができる。C++のテンプレート関数の
ようなものである。
• アドホック多相 ― 型引数に型クラスという制約
をつけて全称量化することができる。C++の関
数オーバーロードのようなものである。アド
ホック多相は、Haskellの重要な特徴である。
★★★★★
多相型 polymorphic type
パラメータ多相 parametric polymorphism
アドホック多相 ad-hoc polymorphism
28. 様々な型
• 数値型 Int, Integer, Float, Double, ...
• 文字型 Char (文字列型は[Char])
• リスト型 [a]
• ユニット型 ()
• タプル型 (a,b,c)
• 関数型 a->b
★★★★★
29. 関数型
• 関数型は一引数関数を表す。
• 2引数関数は次の2つの表現方法がある。
▫ f :: (a,b)->c
x :: a, y :: b のとき、f (x,y) :: c
▫ f :: a->b->c
x :: a, y :: b のとき、f x y :: c
• Haskellでは2番目をよく用いる。1番目から2番
目への変換をカリー化という。また、「f x」の
ようにすることを部分適用という。
★★★★★
a->b->c = a->(b->c)
f x y = (f x) y
カリー化 currying
部分適用 partial application
31. type → btype [-> type]
btype → {atype}+
atype →
qtycon
| tyvar
| ()
| (type1, ... ,typen)
| [type]
| (type)
simpletype → tycon tyvar1 ... tyvarn
qtycon → [modid .] tycon
tycon → [A..Z] {[a..zA..Z0..9’]}
tyvar → [a..z] {[a..zA..Z0..9’]}
型構築子
型変数
ユニット型
タプル型
型適用
関数型
一文字目は大文字
一文字目は小文字
リスト型
43. datadecl →
data [context =>] simpletype = constr1 | ...
[deriving]
constr →
con [!] atype1 ... [!] atypek
| (btype | !atype) conop (btype | !atype)
| con {var11, ..., var1m :: (type1 | !atype1), ...}
deriving →
deriving qtycls
| deriving (qtycls, ...)
con → conid | (consym)
conop → consym | `conid`
conid → [A..Z] {[a..zA..Z0..9’]}
consym → (: {symbol | :})<reservedop>
44. newtypedecl →
newtype [context =>] simpletype = newconstr
[deriving]
newconstr →
con atype
| con {var :: type}
var → varid | (varsym)
varid → [a..z] {[a..zA..Z0..9’]}
varsym → (symbol {symbol | :})<reservedop>
typedecl → type simpletype = type
45. classdecl →class [scontext =>] tycls tyvar
where {cdecl1; ...}
class → qtycls tyvar | qtycls (tyvar atype1 ... atypen)
context → class | (class1, ..., classn)
simpleclass → qtycls tyvar
scontext → simpleclass | (simpleclass1,...,simpleclassn)
cdecl → vardecl’ | sigdecl | fixitydecl
qtycls → [modid . ] tycls
tycls → [A..Z] {[a..zA..Z0..9’]}
tyvar → [a..z] {[a..zA..Z0..9’]}
46. instdecl→ instance [scontext =>] qtycls inst
[where {idecl1; ...}]
inst →
qtycon
| (qtycon tyvar1 ... tyvarn)
| (tyvar1, ..., tyvarn)
| [tyvar]
| (tyvar1 -> tyvar2)
idecl → vardecl’
48. リテラル
• 整数 123 :: (Num a) => a
• 浮動小数 1.23 :: (Fractional a) => a
• 文字 ‘c’ :: Char
• 文字列 “abc” :: String (=[Char])
★★★★★
53. exp → exp0 [:: [context =>] type]
expi →
expi+1 [qop(n,i) expi+1]
| lexpi
| rexpi
lexpi → (lexpi | expi+1) qop(l,i) expi+1
rexpi → expi+1 qop(r,i) (rexpi | expi+1)
qop → qvarsym | `qvarid` | qconsym | `qconid`
qvarsym → [modid . ] varsym
qvarid → [modid . ] varid
qconsym→ [modid . ] consym
qconid → [modid . ] conid
型シグネチャ
中置演算子の処理
54. exp10 →
¥ apat1 ... apatn -> exp
| let {decl1; ...} in exp
| if exp then exp else exp
| case exp of {alt1; ...}
| doexp
| {aexp}+
alt →
pat -> exp [where {decl1; ...}]
| pat {| exp0 -> exp}+ [where {decl1; ...}]
ラムダ式
局所宣言
if式
case式
do式
関数適用
55. aexp →
qvar
| qcon
| literal
| (exp)
| (exp1, ..., expn)
| [exp1, ..., expn]
| [exp1 [, exp2] .. [exp3]]
| [exp | qual1, ..., qualn]
| (expi+1 qop(a,i))
| (lexpi qop(l,i))
| (qop(a,i)
<-> expi+1)
| (qop(r,i)
<-> rexpi)
| qcon {qvar1=exp1; ...}
| aexp<qcon> {qvar1=exp1; ...}
等差数列リスト
タプル
リスト
リスト内包記法
セクション
データの構築
データの更新
56. pat → pat0
pati →
pati+1 [qconop(n,i) pati+1]
| lpati
| rpati
lpati → (lpati | pati+1) qconop(l,i) pati+1
rpati → pati+1 qconop(r,i) (rapti | pati+1)
中置演算子の処理
57. pat10 →
apat
| gcon apat1 ... apatn
apat →
var
| var [@ apat]
| qcon {qvar1=pat1, ...}
| literal
| _
| (pat1, ... , patn)
| [pat1, ..., patn]
| ~apat
| (pat)
データ構築子
変数
アズパターン
ラベル付きデータ構築子
リテラル
ワイルドカード
タプル
リスト
反駁不可パターン
59. vardecl → (funlhs | pat0) rhs
vardecl’→ (funlhs | var) rhs
funlhs →
var {apat}+
| pati+1 varop(a,i) pati+1
| lpati varop(l,i) pati+1
| pati+1 varop(r,i) rpati
| (funlhs) {apat}+
rhs →
= exp [where {decl1; ...}]
| {| exp0 = exp}+ [where {decl1; ...}]
61. モナドの意味
-- m a は a の型の値を出力する計算である。
class Monad m where
-- x >>= f は計算 x の結果を f に渡し、
-- 新たな計算を得るということである。
(>>=) :: m a -> (a -> m b) -> m b
-- return c は値cを返す単純な計算である。
return :: a -> m a
64. doexp → do {stmt1; ...; stmtn; exp}
stmt →
exp
| pat <- exp
| let {decl1; ...}