静岡developers勉強会 第3回haskell読書会 第4章関数定義 発表資料
DESCRIPTION
平成22年(2010年)静岡Developers勉強会 第3回Haskell読書会 第4章「関数定義」発表資料 ※読書会で使用した資料に改訂を加えています。TRANSCRIPT
静岡Developers勉強会第三回 Haskell読書会平成22年3月27日(土)
第4章 関数定義発表者 伊藤 聖修 id:kynbit
静岡Developers勉強会第三回 Haskell読書会平成22年3月27日(土)
第4章 関数定義発表者 伊藤 聖修 id:kynbit
Agenda
関数を定義する方法を学ぶ
関数を定義する方法1.条件式
2.ガード
3.パターンマッチ
4.λ式
5.セクション
4.1 古きから新しきへ
4.1 古きから新しきへ
関数を定義する方法で一番簡単な方法は既存の関数を組み合わせること
4.1 古きから新しきへ
• isDigit >= , ∧• even mod , ==• splitAt take, drop • recip /
4.1 古きから新しきへ
• isDigit ‘2’• even 2• splitAt 2 [1..5]• recip 2
関数を定義する方法1.条件式
2.ガード
3.パターンマッチ
4.λ式
5.セクション
4.2 条件式
Haskellでは、候補の中から結果を一つ選択する方法を用意している
4.2 条件式
Photo courtesy Photos8.com
4.2 条件式
•条件式 … 条件(if then else)と呼ばれ る論理的な式を使って、同じ 型の2つの候補の中から一方 を選び出す … 条件がTrue … 1番目の結果 条件がFalse … 2番目の結果
4.2 条件式
hoge :: Int -> Inthoge n = if n >= 0 then n else - n
4.2 条件式
• abs 2• abs -2• abs (-2)
4.2 条件式
• signum 2• signum -2• signum (-2)
4.2 条件式•Haskellの条件式では必ずelse部を持たなくてはならない
•「ぶらさがりelse問題」を回避可能 if 静岡文化会館 == True if Haskell読書会 == True you = smart else you = not smart
4.2 条件式
•signumの場合signum :: Int -> Intsignum n = if n < 0 then -1 else if n == 0 then 0 else 1
4.2 条件式
hoge :: Int -> Inthoge n = if True then if False then 1 else 2
関数を定義する方法1.条件式
2.ガード
3.パターンマッチ
4.λ式
5.セクション
4.3 ガード付きの等式
4.3 ガード付きの等式
•ガード付きの等式 … ガードと呼ばれる論理式を並 べ、列挙された同じ型の候補 の中から結果を選び出す … 最初のガードがTrue … 1番目の結果 2つ目のガードがTrue … 2番目の結果 3つ目のガードがTrue … 3番目の結果
4.3 ガード付きの等式
hoge n | n < 0 = -1 | n == 0 = 0 | otherwise = 1
4.3 ガード付きの等式
•条件式と比較して優れている点1.条件が多くなったときに見やすい
2.ガード otherwise が「他の全ての場合」を処理してくれて便利
休憩
Agenda
関数を定義する方法を学ぶ
関数を定義する方法1.条件式
2.ガード
3.パターンマッチ
4.λ式
5.セクション
4.4 パターンマッチ
パターンマッチを使うことで、関数の多くは、定義が完結かつ直感的になる
4.4 パターンマッチ
Photo courtesy Photos8.com
4.4 パターンマッチ
•パターンマッチ … パターンと呼ばれる式が並べ られ、列挙された同じ型の候 補の中から結果を選ぶ … 最初のパターンに合致 … 1番目の結果 2つ目のパターンに合致 … 2番目の結果 3つ目のパターンに合致 … 3番目の結果
4.4 パターンマッチ
• 引数が1つの場合mynot :: Bool -> Boolmynot False = Truemynot True = False
4.4 パターンマッチ• 引数が2つの場合( @@ ) :: Bool -> Bool -> BoolTrue @@ True = TrueTrue @@ False = FalseFalse @@ True = FalseFalse @@ False = False
4.4 パターンマッチ•ワイルドカード「_」を使う場合( @@ ) :: Bool -> Bool -> BoolTrue @@ True = True_ @@ _ = False
4.4 パターンマッチ
•ワイルドカードを使うと、遅延評価の下では、1番目の引数が False であれば、2番目の引数を評価することなく結果が返せる
4.4 パターンマッチ
•論理演算子( && )の、標準ライブラリ上の定義
True ( && ) b = b False ( && ) _ = False
4.4 パターンマッチ
•2つ以上の引数が同じ名前を持つことは許されない
b ( @@ ) b = b _ ( @@ ) _ = False
4.4 パターンマッチ
•2つ以上の引数が同等であるかを確かめたいならばガードを使う
b ( @@ ) c | b == c = b | otherwise = False
Agenda
関数を定義する方法を学ぶ
4.4 パターンマッチ• タプルパターン• 1番目の要素を取り出すライブラリ関数fst :: ( a, b) -> afst ( x, _ ) = x
• 2番目の要素を取り出すライブラリ関数snd :: ( a, b ) -> bsnd ( _, y ) = y
4.4 パターンマッチ• リスト・パターン• リストの要素数が3つで、先頭の要素が文字 ’a’ であるか調べる関数
hoge :: [ Char ] -> Boolhoge [ ‘a’, _ , _ ] = Truehoge _ = False
4.4 パターンマッチ
• リスト・パターン• リストは、空リスト [ ] に、演算子 : ( cons演算子 )を使って、要素を1つづつ先頭に追加していくことで生成する
4.4 パターンマッチ
• リスト・パターン• [ 1, 2, 3 ]= 1 : [ 2, 3 ]= 1 : ( 2 : [ 3 ] )= 1 : ( 2 : ( 3 : [ ] )
• 1 : 2 : 3 : [ ] と右結合で扱う
4.4 パターンマッチ• リスト・パターン• リストの先頭の要素が文字 ’a’ であるか調べる関数
hoge :: [ Char ] -> Boolhoge ( ‘a’ : _ ) = Truehoge _ = False
4.4 パターンマッチ
• リスト・パターン• ライブラリ関数 null , head , tail
• 関数適用は演算子よりも結合順位が高いため、cons演算子を使ったパターンは括弧で囲む tail _ : xs = xs ⇔ ( tail _ ) : xs = xs
4.4 パターンマッチ• n + k パターン• n … 整数の変数• k … 0より大きい整数の定数
pred :: Int -> Intpred 0 = 0pred ( n + 1 ) = n
4.4 パターンマッチ
• n + k パターンの注意点1.k 以上である整数のみに合致する
2. ( n + k ) などと括弧でパターンを個囲む必要がある
休憩
Agenda
関数を定義する方法を学ぶ
関数を定義する方法1.条件式
2.ガード
3.パターンマッチ
4.λ式
5.セクション
4.5 λ式
4.5 λ式
1. 無名関数を作成可能
2.「引数のパターン」と「引数から結果を計算 する方法を指名した本体」から成る
4.5 λ式
•¥x -> x + x• (¥x -> x + x) 2
4.5 λ式1.カリー化された関数の形式的な意味付けに利用可能
2.カリー化の結果としてではなく、本質的に関数を返す場合に便利
3.一度しか参照されない関数の名前付を避けられる
4.5 λ式1.カリー化された関数の形式的な意味付けに利用可能
• add x y = x + y• add = ¥x -> ( ¥y -> x + y )
4.5 λ式2.カリー化の結果としてではなく、本質的に関数を返す場合に便利
myconst :: a -> ( b -> a)
myconst x = ¥_ -> x
4.5 λ式
3.一度しか参照されない関数の名前付けを避けられる
odds n = map (¥x -> x*2 + 1)[0..n-1]
関数を定義する方法1.条件式
2.ガード
3.パターンマッチ
4.λ式
5.セクション
4.6 セクション
4.6 セクション•演算子 … 引数の間に置かれる関数 ex. +, * , / , etc. … 引数を2つ取る関数もバッ ククォートで囲まれると演 算子になる ex. 3`div`2
•演算子のカリー化 … 括弧で囲む ex. (+) 1 2
4.6 セクション
部分適用を使い引数を一つだけ渡した二項演算子のこと
4.6 セクション
• が演算子なら式( ), ( x ),( y)いずれも セクション
•セクションのλ式による形式化( ) = λx → (λy → x y )( x ) = λy → x y( y ) = λx → x y
++
+ +
++
++
+
+
4.6 セクション•セクションの主な利用方法1.有益な関数を簡潔な形で定義可能
2.演算子の型を宣言する際に必要
3.他の関数に二項演算子を引数として渡すとき必要
4.6 セクション1.有益な関数を簡潔な形で定義可能
• ( + ) 1 2• 2 ( 1 + ) ※エラーが出る• ( 1 / ) 2• 4 ( * 2 ) ※エラーが出る• 5 ( / 2 ) ※エラーが出る
4.6 セクション2.演算子の型を宣言する際に必要… Haskell では演算子そのものは 正しい式ではない
• :type &&• :type ( && )
4.6 セクション3.他の関数に二項演算子を引数として渡すとき必要
• 畳込関数 folder • 引数 , xs• 定義 f [ ] = v f ( x : xs ) = x f xs
• 演算子 と リストxs を引数に取り、リストの全値に対して演算子 を行う
+
+
+
+
4.6 セクション3.他の関数に二項演算子を引数として渡すとき必要
• and をセクションを使わずに定義 and [ ] = True and ( x : xs ) = x && and xs
• and をセクションを使って定義 and :: [ Bool ] -> Bool and = foldr ( && ) True
4.7 この章の参考文献
•関数の引数以外にもパターンマッチやガードを使いたいときは、case式を用いる
•無名関数λは関数理論λ計算に基づく
Agenda
関数を定義する方法を学ぶ
4.8 練習問題
おわりに
•λ 式の48%は宇宙の意思で出来ています•λ 式の38%は柳の樹皮で出来ています•λ 式の9%は気の迷いで出来ています•λ 式の4%はマイナスイオンで出来ています•λ 式の1%はお菓子で出来ています
ご静聴ありがとうございました