Haskell勉強会

関数型プログラミングの学習日記

Haskellの特徴

Haskellって、何がメリットなの?

 

haskell.hatenablog.com

 

(「イントロダクション」p.v ~)

 

 

Haskellって何なの?

Haskellの学習に際して、まずはHaskellの特徴が紹介されてました。

 

Haskellは純粋関数型プログラミング言語

 

例えば、「ある数の階乗とは1からその数までの積である」というような定義をコンピュータに伝えます。
あるいは、「数のリストの和とは先頭の数と残りのリストの和を足し合わせたものである」などと。
これらはどちらも関数として書くことができます。

 

プログラミング・パラダイム 

プログラミング言語の「パラダイム」(プログラムの組み立て方、考え方)には、主に2つあります。

  1. 命令型 (参考:命令型プログラミング - Wikipedia
  2. 宣言型 (参照:宣言型プログラミング - Wikipedia

 

Haskellは、「宣言型」のパラダイムなんですね。

 

プログラミング言語の種類

宣言型をさらに細分化すると、(命令型も含めて)プログラミング言語の種類は、主に4つに分類できます。

 

(参考)「日経ソフトウエア」2008年3月号(p.55)

分類 基礎となる計算モデル 事例
手続き型言語 チューリングマシン C, Java
問い合わせ言語 (非手続き型言語 関係モデル SQL
関数型言語 ラムダ計算 Lisp, Haskell
論理型言語 一階述語言語 Prolog

 

(1) 手続き型言語:  C、JavaPython

(2) 問い合わせ言語: SQL

(3) 関数型言語:   LispHaskell

(4) 論理型言語:   Prolog

などがあります。

 

  • 命令型プログラミング → (1) 手続き型
  • 宣言型プログラミング → (2) 問合せ型、(3) 関数型、(4) 論理型

 

計算モデル

数学的説明の詳細はよく分かりませんが、

は、コンピューターの側から見れば同じもので、

  • 命令型でできることは、関数型でもできるし、
  • またその逆に、関数型でできることは、命令型でもできる

ようです。(安心)

 

(参考)ラムダ計算 - Wikipedia

ラムダ計算は1つの変換規則(変数置換)と1つの関数定義規則のみを持つ、最小の(ユニバーサルな)プログラミング言語であるということもできる。

ここでいう「ユニバーサルな」とは、全ての計算可能な関数が表現でき正しく評価されるという意味である。

これは、ラムダ計算がチューリングマシンと等価な数理モデルであることを意味している。

チューリングマシンがハードウェア的なモデル化であるのに対し、ラムダ計算はよりソフトウェア的なアプローチをとっている。

 

プログラミング言語の好き嫌いで、派閥争いをすることは無意味だから、お互いに仲良くして、良い所取りをしよう!w

 

変数はimmutable

関数型プログラミングでは、一度変数の値を設定すると、後でそれを別の値に変更することはできません

 

「a = 5」とした後に「a = 10」とかに変更ができない、ってどういうこと???

それって、「変数」じゃなくて「定数」みたいなもんなの???

…と謎は深まるばかりです。

 

状態を変更できない性質・特徴は、「immutable」(イミュータブル:不変)というそうです。

本書をジックリ読んで、この謎を解明していきたいです!

 

(参考)イミュータブル - Wikipedia

イミュータブル(immutable)なオブジェクトとは、作成後にその状態を変えることのできないオブジェクトのことである。

対義語はミュータブル(mutable)なオブジェクトで、作成後も状態を変えることができる。

 

関数は副作用を持たない

純粋関数型言語では、関数は副作用を持ちません。

関数にできることは、何かを計算してその結果を返すことだけです。

 

これは最初のうちは制約に思うかもしれませんが、実はとてもうれしい効能があります。

関数が同じ引数で2回呼ばれたら、これらは同じ値を返すことが保証されます。

この性質は参照透明性と呼ばれています。

 

そのおかげで、プログラマは関数の正しさを簡単に推測(時には証明さえ)できます。

正しいと分かっている単純な関数を組み合わせて、より複雑な正しい関数を組み立てられるのです。

 

関数型プログラミングをやってみたい理由は、これに尽きますね?

  • 副作用を持たない。=副作用を分離して管理できる。
  • 参照透明性(参照透過性)が保証されている。=テストを簡素化できる。

 

(参考)

副作用 (プログラム) - Wikipedia

プログラミングにおける副作用(ふくさよう)とは、ある機能がコンピュータの(論理的な)状態を変化させ、それ以降で得られる結果に影響を与えることをいう。

代表的な例は変数への値の代入である。

 

参照透過性 - Wikipedia

  1. 同じ条件を与えれば必ず同じ結果が得られる
  2. 他のいかなる機能の結果にも影響を与えない

 

遅延評価

Haskellは怠け者です。

特にそうしろと言われた場合を除いては、結果が必要になるまで関数を実行しないのです。

この振る舞いは、専門用語では遅延評価といいます。

遅延評価は、見かけ上無限の大きさのデータを扱うことを可能にします。

 

この機能は、別になくても良いかな~。

(自分の用途では、あまり遅延評価によって受けられる恩恵はなさそうなのでw)

まあでも、必要に応じて使えるカードがたくさんあるってのは、良いことでしょうね?

 

(参考)

遅延評価 - Wikipedia

遅延評価(lazy evaluation)や必要呼び(call-by-need)は評価戦略の一種類であり、非正格な関数型言語で使用もされる。

対義語は先行評価(eager evaluation)。

評価しなければならない値が存在するとき、実際の計算を値が必要になるまで行わないことをいう。

遅延評価を行う利点は計算量の最適化である。

 

ストリーム (プログラミング) - Wikipedia

ストリーム(stream)とはデータを「流れるもの」として捉え、流れ込んでくるデータを入力、流れ出ていくデータを出力として扱う抽象データ型である。

関数型言語においては専ら、無限の大きさ(長さ、要素数)の再帰的なデータ構造を指す。

遅延評価を用いて実装されるため「遅延ストリーム」とも呼ばれる。 

 

静的型付け言語

これはどのコード片が数で、どれが文字列で、といったことをコンパイラがプログラムのコンパイル時にすべて知っているということです。

静的型付けは、コンパイル時にたくさんのエラーの要因を捕まえてくれます。

 

(参考)

静的型付け - Wikipedia

静的型付け(static typing)とは、プログラミング言語で書かれたプログラムにおいて、変数や、サブルーチンの引数や返り値などの値について、その型が、コンパイル時など、そのプログラムの実行よりも前にあらかじめ決められている、という型システムの性質のことである。

 

型システム - Wikipedia

型システム(type system)とは、プログラミング言語において、その式などの部分が持つ値を、その種類(型(type)、データ型も参照)に沿って分類し、プログラムが正しく振る舞うこと、といった性質について保証する手法である。

 

型検査は、バグを防ぐために役立ちます。

 

togetter.com

 

肛門 「何者だ!」

うんこ「おならです」

肛門 「よし、通れ!」 

 

http://bokete.jp/odai/737937

f:id:hamamuratakuo:20170821182609p:plain

 

→ 関数が引数のデータ型をチェックしていれば、その後の大惨事は防げたでしょうw

 

型推論 

プログラマがすべてのコード片に対して明示的に型を書かなくても、Haskellの賢い型システムは自分でそれを推論できるのです。 

型推論のおかげで、汎用性の高いコードを書くのが簡単になります。 

 

(参考)型推論 - Wikipedia

型推論とはプログラミング言語の機能の1つで、静的な型付けを持つ言語において、変数や関数の型を宣言しなくてもそれを導くのに使われた関数の型シグネチャなどから自動的に型を決定する機構のこと。

推論に失敗するとその時点でエラーを報告できるため、少なくとも誤った型を用いる事によるバグは回避できる。

 

エレガントで簡潔 

通常Haskellのプログラムは、命令型で書かれた同等のものと比べて短くなります。

短いプログラムは保守しやすく、含まれるバグも少なくなります。

 

まとめ

Haskellには、こんな特徴があるんですね?

 

Haskellを勉強したら、天才ハッカーになれそうな予感!?(・∀・)

Haskellを勉強するのが、楽しみ~~~!!!

 

…と、無理矢理モチベーションを上げたところで、さっそく次に行ってみたいと思います。

Haskell(GHCi)のインストール★

 

 

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!