[解決済み】Haskellの入門編
質問
ここ数日、Haskellの関数型プログラミングのパラダイムについて、頭を整理しようとしている。チュートリアルを読んだり、スクリーンキャストを見たりしてやってみたのですが、どうもうまくいかないのです。 C、Java、PHPのような様々な命令型/OO言語の学習において、演習は私にとって良い方法だった。しかし、Haskellの能力をよく知らないし、利用すべき新しい概念も多いので、何から始めたらいいのかわからないのです。
では、どのようにHaskellを学んだのでしょうか?何がきっかけで、本当に氷を砕いたのですか?また、初歩の練習について何か良いアイデアがあれば教えてください。
解き方は?
このガイドは、あなたがHaskellを使いこなすレベルに合わせて、全くの初心者からエキスパートまで順番に説明していきます。このプロセスは何ヶ月も(何年も?)かかるので、かなり長くなることに注意してください。
全くの初心者の方
まず、Haskellは十分な技術があれば、何でもできます。非常に高速で(私の経験ではCとC++に次ぐ)、シミュレーションからサーバー、GUI、Webアプリケーションまで、何にでも使うことができます。
ただ、Haskellで初心者が書きやすい問題というのは、他よりもあります。数学の問題やリストプロセスのプログラムなどは、Haskellの最も基本的な知識だけで書けるようになるので、良い候補になると思います。
Haskellの基本を学ぶのに良いガイドがいくつかあります。 Haskellを楽しく学ぶチュートリアル の最初の6章と Haskellを学ぶといいことがある (またはその JupyterLabの適応 ). これらを読みながら、自分が知っていることを使って簡単な問題を解いてみるのも非常に良いアイデアです。
もう2つの良い資料は Haskell プログラミングの基礎 と Haskellでプログラミング . どちらも各章に練習問題がついているので、最後の数ページで学んだことに合わせて小さな簡単な問題を解くことができます。
試してみると良い問題集は ハスケル99の問題集ページ . これらは非常に基本的なものから始まり、先に進むにつれて難しくなっていきます。再帰と高次関数のスキルを練習することができるので、これらの問題をたくさん解くことはとても良い練習になります。ランダム性を必要とする問題は、Haskellでは少し難しいので、スキップすることをお勧めします。チェック このSO問題 QuickCheckで解答をテストしたい場合 ( 中級編 の下にあります)。
をいくつかこなしたら、今度は プロジェクト・オイラー の問題です。これらの問題は、何人がクリアしたかによってソートされており、難易度の目安としてかなり有効です。これらの問題は、前の問題よりもあなたの論理とHaskellをテストしますが、それでも最初の数問はできるはずです。これらの問題でHaskellが持つ大きな利点は、整数のサイズに制限がないことです。これらの問題のいくつかは、learn you a Haskellの7章と8章を読んでおくと便利です。
初級編
その後、再帰と高次関数についてかなり理解できたと思いますので、より現実的な問題に着手するのに良い時期でしょう。手始めとして非常に良いのは リアルワールドHaskell (オンラインブック、ハードコピーも購入できます)。 最初の数章は、関数型プログラミングや再帰を使ったことがない人にとっては、あまりに早く多くのことが紹介されていると感じました。しかし、これまでの問題集で練習していれば、完全に理解できるはずです。
この本の問題を解くことは、Haskellで抽象化を管理し、再利用可能なコンポーネントを構築する方法を学ぶのに最適な方法である。Haskellには通常のオブジェクト指向プログラミング(ooクラス)がないので、オブジェクト指向プログラミングに慣れている人には不可欠です(Haskellにも型クラスはありますが、ooクラスとは全く異なり、ooインターフェースに近いものです)。各章には、後の章で使われる新しいアイデアがたくさん紹介されているので、章を飛ばすのはあまり良い考えではないと思います。
しばらくすると、第14章、恐るべきモナドの章に入ります(ダダダダダダダダ)。Haskellを学ぶほとんどの人は、モナドの概念があまりに抽象的なため、理解するのに苦労します。他の言語では、関数型プログラミングにおけるモナドほど抽象的な概念はないと思います。モナドは、多くのアイデア(IO操作、失敗するかもしれない計算、パース、...)を1つのアイデアに統一することを可能にします。ですから、モナドの章を読んでも、よくわからなくてもがっかりしないでください。私は、モナドに関するさまざまな説明を読むことが有益だと思いました。それぞれの説明が、この問題に対する新しい視点を与えてくれます。以下は、とても良い モナドのチュートリアル一覧 . を強くお勧めします。 モナドのすべて しかし、他のものも良いものです。
また、コンセプトが本当に身につくまでには、しばらく時間がかかります。これは、使うことで得られるものですが、同時に、時間をかけることでも得られます。私は、ある問題について寝ることが何よりも助けになると感じています。やがて考えがまとまり、本当はとてもシンプルな概念を理解するのに苦労したことを不思議に思うようになります。そうなれば、Haskellがあなたのお気に入りの命令型プログラミング言語になるかもしれませんね(笑)。
Haskellの型システムを完璧に理解しているかどうかを確認するために、以下の問題を解いてみてください。 ハスケル中級演習20題 . これらの演習では、"furry" や "banana" などの楽しい関数名を使って、基本的な関数プログラミングの概念を理解することができます(まだ持っていない場合)。矢印、ユニコーン、ソーセージ、毛皮のようなバナナで覆われた紙の束で夜を過ごすには良い方法です。
中級編
Monadsを理解したら、Haskellプログラマの初級者から中級者への移行が完了したと思います。では、ここから先はどうすればいいのか?まず、私がお勧めするのは(まだモナドの学習で学んでいないのであれば)、Reader、Writer、Stateといった様々なタイプのモナドです。これもReal world HaskellとAll about monadsに詳しく載っています。モナドの学習を完了させるには、モナド変換器を学ぶことが必要です。モナドトランスフォーマーは、異なるタイプのモナド(例えば、ReaderとStateのモナド)を1つにまとめることができるものです。最初は役に立たないように見えるかもしれませんが、しばらく使っているうちに、これなしでどうやって生きてきたのか不思議に思うようになります。
これで、実戦的なHaskellの本を読み終えても大丈夫です。モナドを使いこなせれば、章を飛ばしても問題ないでしょう。興味のある章を選べばいいのです。
今ある知識で、cabalのほとんどのパッケージ(少なくともドキュメント化されているもの)と、Haskellに付属するほとんどのライブラリを使えるようになるはずです。試してみると面白いライブラリのリストがあります。
-
パーセク : プログラムやテキストのパース用。正規表現を使うよりずっといい。優れたドキュメントで、実際のHaskellの章もある。
-
クイックチェック : とてもクールなテストプログラムです。常に真であるべき述語を書く(例えば
length (reverse lst) == length lst
). QuickCheck はたくさんのランダムな値(この場合はリスト)を生成し、すべての結果に対して述語が真であることをテストします。また オンラインマニュアル . -
HUnit : Haskellのユニットテスト。
-
gtk2hs : Haskell 用の最も人気のある GUI フレームワークで、gtk アプリケーションを書くことができます。
-
ハッピースタック : Haskell用のWeb開発フレームワーク。データベースを使わず、データ型ストアで代用する。かなり良いドキュメントがある(他の有名なフレームワークは スナップ と ヨーソド ).
また、いずれは学ぶべき概念(モナドの概念など)がたくさんあります。モナドの抽象度の高さに脳が慣れるので、最初に学ぶより簡単でしょう。これらの高レベルの概念とそれらがどのように組み合わされるかを学ぶための非常に良い概要が タイプ・ペディア(Typeclassopedia .
-
アプリケーティブ。モナドのようなインターフェイスだが、あまり強力ではない。すべてのモナドはApplicativeであるが、その逆はない。これは、ApplicativeでありながらMonadsでない型がいくつかあるため、便利です。また、Applicative関数を使って書かれたコードは、Monad関数を使って同等のコードを書くよりも、しばしばよりコンポーザブルです。参照 ファンクタ、Applicative Functors、Monoids をご覧ください。
-
折り畳み式 , トラバーサブル : リストの操作の多くを抽象化した型クラスで、同じ関数を他のコンテナ型に適用することができます。また ハスケルWikiの説明 .
-
モノイド : Monoidは、ゼロ(またはmempty)値を持つ型であり、操作の表記は
<>
のように、2つのモノイドを結合する。x <> mempty = mempty <> x = x
とx <> (y <> z) = (x <> y) <> z
. これらは同一性原理と連想原理と呼ばれる。数値のような多くの型はMonoidsでmempty = 0
と<> = +
. これはいろいろな場面で役に立つ。 -
矢印 : 矢印は、入力を受けて出力を返す計算を表す方法です。関数は最も基本的な矢印の種類ですが、他にも多くの種類があります。また、このライブラリには、矢印を操作するための非常に便利な関数がたくさん用意されている。
-
配列 Haskell の様々な可変長配列と不変長配列。
-
STモナド : では、モナドの外側で純粋さを保ちつつ、非常に高速に実行されるミュータブルな状態を持つコードを書くことができます。詳しくはリンク先をご覧ください。
-
FRP: Functional Reactive Programming。イベント、トリガー、入出力(guiなど)を処理するコードの新しい実験的な書き方である。でも、これについてはよく知らないんです。 ポール・フーダックのヤンパ談義 が良いきっかけになると思います。
新しい言語機能がたくさんあるので、ぜひ見てみてください。Googleで検索すれば、たくさんの情報が見つかります。 ハッシュケルウィキブックス のサイト、haskellwiki.orgのサイト、そして ghc ドキュメント .
- マルチパラメーター型クラス/機能依存性
- タイプファミリ
- 存在量化された型
- ファントムタイプ
- GADTS
- その他...
Haskellの多くは カテゴリー理論 ということで、それについて調べてみるのもいいかもしれません。出発点として良いのは コンピュータサイエンティストのためのカテゴリー理論 . 本を買いたくない人は、著者の関連する 記事 も素晴らしいです。
最後に、様々なHaskellツールについてもっと学びたいと思うでしょう。これらは以下の通りです。
- ghc (およびそのすべての機能)
- カバール Haskell のパッケージシステム
- ダルク Haskell で書かれた分散バージョン管理システムで、Haskell プログラムに非常によく使われています。
- ハドドック : Haskell の自動ドキュメント生成ツール
これらの新しいライブラリやコンセプトを学ぶ一方で、Haskellで適度な規模のプロジェクトを書いておくと非常に便利です。プロジェクトは何でも構いません(例えば、小さなゲーム、データアナライザー、ウェブサイトなど。 コンパイラ ). これに取り組むことで、今学んでいることの多くを応用できるようになります。このレベルに何年もとどまることになります(私はこのレベルです)。
専門家
この段階に到達するまでには何年もかかりますが(2009年からこんにちは!)、ここからは博士論文を書いたり、新しいghc拡張をしたり、新しいアブストラクションを考え出したりするのでしょうね。
ヘルプを得る
最後に、学習のどの段階においても、情報を得るための場所は複数あります。それらは以下の通りです。
- haskell ircチャンネル
- その メーリングリスト . これらは、行われる議論を読むだけでも登録する価値があり、中には非常に興味深いものもあります。
- その他、haskell.orgのホームページに掲載されている場所
結論
予想以上に長くなってしまった......。とにかく、Haskellに熟達するのはとても良いことだと思います。時間はかかりますが、それは主に、そうすることでまったく新しい考え方を学ぶことになるからです。また、Haskellを学んだ結果、アイデアを抽象化する新しい方法をたくさん目にするようになり、オブジェクト指向プログラミングのスキルが向上したことを実感しています。
関連
-
[解決済み] haskellでCharからIntに変換する
-
[解決済み] Haskellの[]と':'とは何ですか?
-
[解決済み] Project Eulerとの速度比較。CとPythonとErlangとHaskellの比較
-
[解決済み】代数的なデータ型の代数を悪用する - なぜこれが有効なのか?
-
[解決済み】ミュータブルステートなしで何か役に立つことができるのか?
-
[解決済み】Template Haskellの何がそんなに悪いのか?
-
[解決済み】一般的なHaskellの演算子で発音可能な名前はありますか?[クローズド]
-
[解決済み】テンプレートHaskellで関連する型の同義語を取得する
-
[解決済み】Haskell/GHCの`forall`キーワードは何をするのですか?
-
[解決済み] ステートレス・プログラミングのメリット?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Haskellの[]と':'とは何ですか?
-
[解決済み] Haskell takeWhile + 1
-
[解決済み】代数的なデータ型の代数を悪用する - なぜこれが有効なのか?
-
[解決済み】Template Haskellの何がそんなに悪いのか?
-
[解決済み】Haskell: リスト、配列、ベクトル、シーケンス
-
[解決済み】-XAllowAmbiguousTypesはいつが適切ですか?
-
[解決済み】なぜモナドが必要なのか?
-
[解決済み】テンプレートHaskellで関連する型の同義語を取得する
-
[解決済み】Haskell の `data` と `newtype` の違いについて
-
[解決済み】Haskell/GHCの`forall`キーワードは何をするのですか?