狠狠撸

狠狠撸Share a Scribd company logo
Haskell超入門 Part.2
?   Nabe

?   Twitter / Facebook / Hatena
    nabe256
Haskell超入門 Part.2
?   贬补蝉办别濒濒におけるクロージャ
?   Twitterの某発言から
    ? @rizumita: @nabetaro 関数型言語とかクロー
      ジャとかが聞きたいです。話せる人がどれだけ
      いるか分かりませんが…
    ? @nabetaro: 関数型言語というと、話したい人
      がいるんじゃないかな?(他力本願)
    ? @nabe256: Haskellで発表出来るかなぁ???
?   Twitterの某発言から
    ? @rizumita: @nabetaro 関数型言語とかクロー
      ジャとかが聞きたいです。話せる人がどれだけ
      いるか分かりませんが…
    ? @nabetaro: 関数型言語というと、話したい人
      がいるんじゃないかな?(他力本願)
    ? @nabe256: Haskellで発表出来るかなぁ???
?   そんな餌で俺様が釣られクマ――(AA略
? でもクロージャは
  ふいんき(←なぜか変換できない)
  だけしか知らない。
? なので、
  関数型言語Haskellにおける
  クロージャについて
  それっぽい解説を。
? Haskellは初心者レベルです。
? クロージャは名前だけなら知ってるという
  レベルです。
? 色々調べてみましたが、間違いが含まれて
  いる可能性が大いにあります。
? おかしな所があったら是非教えてください。
?   クロージャ(クロージャー、closure、閉
    包)はプログラミング言語における関数の
    一種。引数以外の変数を実行時の環境では
    なく、自身が定義された環境(静的スコー
    プ)において解決することを特徴とする。
    関数とそれを評価する環境のペアであると
    もいえる。
                 (by Wikipedia)
?   なにゆーてんの?
?   典型的には、クロージャはある関数全体が
    他の関数(以下、エンクロージャ)の内部
    で宣言されたときに発生し、内部の関数は
    エンクロージャのローカル変数(レキシカ
    ル変数)を参照する。実行時に外部の関数
    が実行された際、クロージャが形成される。
    クロージャは内部の関数のコードとエンク
    ロージャのスコープ内の必要なすべての変
    数への参照からなる。
                 (by Wikipedia)
?   なにそれ。おいしいの?
?   クロージャは
    関数内で一時的な関数を作るための仕組み。
? 言葉で説明しても難しいので、
  サンプルを作って考えてみる。
? 普通の書き方から。
?   割り算を計算する関数。
    div :: Double -> Double -> Double
    div x y = x / y

?   引数を二つ取り、値を返す関数。

?   使い方
    ghci> div 4 3
    1.3333333333333333
? 式変形をしてみる。
? div’ x y = f
               where
                f=x/y
? 使い方
  ghci> div’ 4 3
  1.3333333333333333
?   div’ x y = f
        where
          f=x/y
? fは外側のdiv’関数(エンクロージャ)の中で
  定義された一時関数(クロージャ)になる。
? クロージャはエンクロージャより外からは
  参照出来ない。
? fからは、エンクロージャの値(x,y)を参照す
  ることが出来る。
? 引数付きの関数も作成可能。
? div’’ x y = f x y
                where
                 fab=a/b
? 使い方
  ghci> div’’ 4 3
  1.3333333333333333
? 二次方程式の解の公式
? roots a b c =
       ((-b + sqrt(b*b – 4*a*c)) / (2*a),
        (-b – sqrt(b*b – 4*a*c)) / (2*a))
? roots a b c =
       ((-b + sqrt(b*b – 4*a*c)) / (2*a),
        (-b – sqrt(b*b – 4*a*c)) / (2*a))
? roots’ a b c =
       ((-b + det) / (2*a),
        (-b – det) / (2*a))
       where det = sqrt(b*b – 4*a*c)
? roots a b c =
       ((-b + sqrt(b*b – 4*a*c)) / (2*a),
        (-b – sqrt(b*b – 4*a*c)) / (2*a))
? roots’ a b c =
       ((-b + det) / (2*a),
        (-b – det) / (2*a))
       where det = sqrt(b*b – 4*a*c)
? 共通部分をひとまとめにして、
  見やすくする事が可能。
? Haskellではwhereとほぼ同じ機能を
  持つものとしてletというものがある。
? whereの前と後を入れ替えたようなもの
  なので、読みやすさや状況によって
  使い分ける。
? 恐らくwhereの方が一般的に使われている。
? 同じ名前で関数定義すると、実際にどちら
  が使われているのか分かりづらい。
  混ぜるな危険。
? 引数の一部だけ指定して定義。
? div x y = x / y
  div4 = div 4
? ghci> div4 3
  1.3333333333333333
? 値を固定した関数を作る事が出来る。
? これもクロージャの一種。
? 定義が必ずしも必要でない書き方。
? div’’’ = ?x -> ?y -> x / y
? 使い方
  ghci> div’’’ 4 3
  1.3333333333333333
  ghci> (?x -> ?y -> x / y) 4 3
  1.3333333333333333
? 同じような事が出来る。
? 使い方によってはこれもクロージャの一種。
? 言語によってクロージャの定義が
  異なったりしています。
? 解説者によっても
  ばらつきがあるように見えます。
? Don’t think. Feel!
?   引数を二つ取り、値を返す関数について。

?   先程の割り算を計算する関数。
    div :: Double -> Double -> Double
    div x y = x / y
?   引数を二つ取り、値を返す関数について。

?   正確には、
    引数を一つ取り、
    [引数を一つ取り、値を返す関数]
    を返す関数。

?   正しい意味を解説すると難しい話に
    なるので、ここでは説明はしない。
?   引数や返り値について
    もう少し詳しく知りたい人は
    「Haskell超入門 Part.1」を見てみると
    もしかしたらわかるかも。

?   確実に理解したい方は、
    もっと詳しく丁寧に説明しているサイトが
    沢山ありますのでとりあえずググれ。
? 先程のdiv関数に小細工。
? div    xy=x/y
? div’’ x y = (/) x y
? div’’’ x = (/) x
? div’’’’   = (/)
? 式変形によって値を消すことが可能。
? 値が無い状態をポイントフリーと呼ぶ。
  (ポイント=値、変数、引数)
? いろんなテクニックがあるので奥が深い。
? ポイントフリーと部分適用を使うと
  関数合成が自由に行える。
? ポイントフリーに限らず、式変形は面白い。
? 詳細はとりあえずググれ。
Q.こんな時、どんな書き方をすれば良いか
  わからないの。
Q.こんな時、どんな書き方をすれば良いか
  わからないの。
A.ググればいいと思うよ。
? クロージャの説明が少なかったので
  調べるのに苦労しました。
? わかりやすいサンプルが作れなかったのが
  残念。
? Haskellは難しいけど楽しいです。

More Related Content

Haskell超入門 Part.2

  • 2. ? Nabe ? Twitter / Facebook / Hatena nabe256
  • 4. ? 贬补蝉办别濒濒におけるクロージャ
  • 5. ? Twitterの某発言から ? @rizumita: @nabetaro 関数型言語とかクロー ジャとかが聞きたいです。話せる人がどれだけ いるか分かりませんが… ? @nabetaro: 関数型言語というと、話したい人 がいるんじゃないかな?(他力本願) ? @nabe256: Haskellで発表出来るかなぁ???
  • 6. ? Twitterの某発言から ? @rizumita: @nabetaro 関数型言語とかクロー ジャとかが聞きたいです。話せる人がどれだけ いるか分かりませんが… ? @nabetaro: 関数型言語というと、話したい人 がいるんじゃないかな?(他力本願) ? @nabe256: Haskellで発表出来るかなぁ??? ? そんな餌で俺様が釣られクマ――(AA略
  • 7. ? でもクロージャは ふいんき(←なぜか変換できない) だけしか知らない。 ? なので、 関数型言語Haskellにおける クロージャについて それっぽい解説を。
  • 8. ? Haskellは初心者レベルです。 ? クロージャは名前だけなら知ってるという レベルです。 ? 色々調べてみましたが、間違いが含まれて いる可能性が大いにあります。 ? おかしな所があったら是非教えてください。
  • 9. ? クロージャ(クロージャー、closure、閉 包)はプログラミング言語における関数の 一種。引数以外の変数を実行時の環境では なく、自身が定義された環境(静的スコー プ)において解決することを特徴とする。 関数とそれを評価する環境のペアであると もいえる。 (by Wikipedia)
  • 10. ? なにゆーてんの?
  • 11. ? 典型的には、クロージャはある関数全体が 他の関数(以下、エンクロージャ)の内部 で宣言されたときに発生し、内部の関数は エンクロージャのローカル変数(レキシカ ル変数)を参照する。実行時に外部の関数 が実行された際、クロージャが形成される。 クロージャは内部の関数のコードとエンク ロージャのスコープ内の必要なすべての変 数への参照からなる。 (by Wikipedia)
  • 12. ? なにそれ。おいしいの?
  • 13. ? クロージャは 関数内で一時的な関数を作るための仕組み。
  • 14. ? 言葉で説明しても難しいので、 サンプルを作って考えてみる。 ? 普通の書き方から。
  • 15. ? 割り算を計算する関数。 div :: Double -> Double -> Double div x y = x / y ? 引数を二つ取り、値を返す関数。 ? 使い方 ghci> div 4 3 1.3333333333333333
  • 16. ? 式変形をしてみる。 ? div’ x y = f where f=x/y ? 使い方 ghci> div’ 4 3 1.3333333333333333
  • 17. ? div’ x y = f where f=x/y ? fは外側のdiv’関数(エンクロージャ)の中で 定義された一時関数(クロージャ)になる。 ? クロージャはエンクロージャより外からは 参照出来ない。 ? fからは、エンクロージャの値(x,y)を参照す ることが出来る。
  • 18. ? 引数付きの関数も作成可能。 ? div’’ x y = f x y where fab=a/b ? 使い方 ghci> div’’ 4 3 1.3333333333333333
  • 19. ? 二次方程式の解の公式 ? roots a b c = ((-b + sqrt(b*b – 4*a*c)) / (2*a), (-b – sqrt(b*b – 4*a*c)) / (2*a))
  • 20. ? roots a b c = ((-b + sqrt(b*b – 4*a*c)) / (2*a), (-b – sqrt(b*b – 4*a*c)) / (2*a)) ? roots’ a b c = ((-b + det) / (2*a), (-b – det) / (2*a)) where det = sqrt(b*b – 4*a*c)
  • 21. ? roots a b c = ((-b + sqrt(b*b – 4*a*c)) / (2*a), (-b – sqrt(b*b – 4*a*c)) / (2*a)) ? roots’ a b c = ((-b + det) / (2*a), (-b – det) / (2*a)) where det = sqrt(b*b – 4*a*c) ? 共通部分をひとまとめにして、 見やすくする事が可能。
  • 22. ? Haskellではwhereとほぼ同じ機能を 持つものとしてletというものがある。 ? whereの前と後を入れ替えたようなもの なので、読みやすさや状況によって 使い分ける。 ? 恐らくwhereの方が一般的に使われている。 ? 同じ名前で関数定義すると、実際にどちら が使われているのか分かりづらい。 混ぜるな危険。
  • 23. ? 引数の一部だけ指定して定義。 ? div x y = x / y div4 = div 4 ? ghci> div4 3 1.3333333333333333 ? 値を固定した関数を作る事が出来る。 ? これもクロージャの一種。
  • 24. ? 定義が必ずしも必要でない書き方。 ? div’’’ = ?x -> ?y -> x / y ? 使い方 ghci> div’’’ 4 3 1.3333333333333333 ghci> (?x -> ?y -> x / y) 4 3 1.3333333333333333 ? 同じような事が出来る。 ? 使い方によってはこれもクロージャの一種。
  • 25. ? 言語によってクロージャの定義が 異なったりしています。 ? 解説者によっても ばらつきがあるように見えます。 ? Don’t think. Feel!
  • 26. ? 引数を二つ取り、値を返す関数について。 ? 先程の割り算を計算する関数。 div :: Double -> Double -> Double div x y = x / y
  • 27. ? 引数を二つ取り、値を返す関数について。 ? 正確には、 引数を一つ取り、 [引数を一つ取り、値を返す関数] を返す関数。 ? 正しい意味を解説すると難しい話に なるので、ここでは説明はしない。
  • 28. ? 引数や返り値について もう少し詳しく知りたい人は 「Haskell超入門 Part.1」を見てみると もしかしたらわかるかも。 ? 確実に理解したい方は、 もっと詳しく丁寧に説明しているサイトが 沢山ありますのでとりあえずググれ。
  • 29. ? 先程のdiv関数に小細工。 ? div xy=x/y ? div’’ x y = (/) x y ? div’’’ x = (/) x ? div’’’’ = (/)
  • 30. ? 式変形によって値を消すことが可能。 ? 値が無い状態をポイントフリーと呼ぶ。 (ポイント=値、変数、引数) ? いろんなテクニックがあるので奥が深い。 ? ポイントフリーと部分適用を使うと 関数合成が自由に行える。 ? ポイントフリーに限らず、式変形は面白い。 ? 詳細はとりあえずググれ。
  • 33. ? クロージャの説明が少なかったので 調べるのに苦労しました。 ? わかりやすいサンプルが作れなかったのが 残念。 ? Haskellは難しいけど楽しいです。