ここ数日、Haskell の関数型プログラミング パラダイムを理解しようと努めてきました。チュートリアルを読んだり、スクリーンキャストを見たりしてこの作業を行いましたが、どれもあまり頭に残りませんでした。現在、さまざまな命令型/OO 言語 (C、Java、PHP など) を学習する際には、演習が私にとって良い方法となっています。しかし、Haskell で何ができるのかよくわからず、活用すべき新しい概念がたくさんあるため、どこから始めればよいのかわかりませんでした。
それで、Haskell をどのように学びましたか? 本当に「きっかけ」となったものは何ですか? また、最初の練習のための良いアイデアはありますか?
ベストアンサー1
このガイドは、Haskell のスキルレベルに応じて、まったくの初心者からエキスパートまで順番に説明します。このプロセスには何ヶ月 (何年?) もかかるため、かなり長くなります。
全くの初心者
まず、Haskell は十分なスキルがあれば何でもできます。Haskell は非常に高速 (私の経験では C と C++ に次ぐ) で、シミュレーションからサーバー、GUI、Web アプリケーションまで、あらゆる用途に使用できます。
ただし、Haskell の初心者にとって他の問題よりも書きやすい問題がいくつかあります。数学の問題やリスト処理プログラムは、書くのに最も基本的な Haskell の知識しか必要としないため、これに適しています。
Haskellの基礎を学ぶのに良いガイドとしては、楽しく学べるHaskellチュートリアルそして最初の6章Haskellを学んで素晴らしい成果を(またはそのJupyterLabの適応これらを読んでいる間に、自分が知っていることを使って簡単な問題を解くことも非常に良い考えです。
もう一つの良いリソースは第一原理からのHaskellプログラミング、 そしてHaskellでのプログラミングどちらも各章ごとに練習問題が付いているので、最後の数ページで学んだ内容に一致する簡単な問題を解くことができます。
試してみるのに良い問題のリストはHaskell 99 問題ページこれらは非常に基本的なことから始まり、進むにつれて難しくなっていきます。これらをたくさんやるのは、再帰や高階関数のスキルを練習するのにとても良い練習になります。ランダム性を必要とする問題はHaskellでは少し難しいので、飛ばすことをお勧めします。チェックこのSOの質問QuickCheck を使用してソリューションをテストする場合 (以下の中級を参照)。
これらをいくつか実行したら、次のいくつかのことに移ることができます。プロジェクト オイラー問題です。これらは、何人が解いたかによって分類されており、難易度の目安になります。これらの問題は、前の問題よりも論理と Haskell のスキルをテストしますが、最初の数問は解けるはずです。これらの問題における Haskell の大きな利点は、整数のサイズに制限がないことです。これらの問題のいくつかを解くには、Learn You a Haskell の第 7 章と第 8 章も読んでおくと便利です。
初心者
その後は、再帰と高階関数についてかなり理解できるようになっているはずなので、もう少し現実的な問題に取り組むのに良い時期でしょう。始めるのにとても良い場所はリアルワールドHaskell(オンライン ブック、ハード コピーも購入できます)。関数型プログラミングをやったことがない、または再帰を使ったことがない人にとっては、最初の数章は紹介が早すぎるように感じました。ただし、前の問題を解いて練習すれば、完全に理解できるはずです。
この本の問題に取り組むことは、Haskell で抽象化を管理し、再利用可能なコンポーネントを構築する方法を学ぶための優れた方法です。これは、オブジェクト指向 (oo) プログラミングに慣れている人にとっては非常に重要です。通常の oo 抽象化メソッド (oo クラス) は Haskell には登場しないからです (Haskell には型クラスがありますが、それらは oo クラスとはまったく異なり、むしろ oo インターフェースに似ています)。各章では後の章で使用される多くの新しいアイデアが紹介されるため、章を飛ばすのは得策ではないと思います。
しばらくすると、第 14 章、恐ろしいモナドの章 (ダダダダ) にたどり着きます。Haskell を学ぶほとんどの人は、モナドの概念が抽象的すぎるため、理解に苦しみます。関数型プログラミングにおけるモナドほど抽象的な概念は、他の言語には思い当たりません。モナドは、多くのアイデア (IO 操作、失敗する可能性のある計算、構文解析など) を 1 つのアイデアに統合します。したがって、モナドの章を読んでも理解できなくても、落胆しないでください。私は、モナドに関するさまざまな説明を読むことが有益だと感じました。それぞれが、問題に対する新しい視点を与えてくれます。ここに、非常に優れたモナドの説明があります。モナドチュートリアルのリスト強くお勧めしますモナドについて、他も良いです。
また、概念が本当に理解されるまでには時間がかかります。これは使用することでも得られますが、時間によっても得られます。時には、問題について寝て考えることが何よりも役立つことがわかっています。最終的には、アイデアが理解でき、実際には非常に単純な概念を理解するのに苦労した理由が不思議に思うでしょう。これが起こると素晴らしいことです。そうなると、Haskell がお気に入りの命令型プログラミング言語になるかもしれません :)
Haskellの型システムを完全に理解しているかどうかを確認するには、次の問題を解いてみてください。中級 Haskell 演習 20 問これらの演習では、「毛皮」や「バナナ」などの楽しい関数名が使用され、基本的な関数型プログラミングの概念をまだ理解していない場合に、理解を深めるのに役立ちます。矢印、ユニコーン、ソーセージ、毛皮のバナナで覆われた紙の束で夜を過ごすのは素敵な方法です。
中級
モナドを理解すれば、初心者の Haskell プログラマーから中級の 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開発フレームワーク。データベースは使用せず、代わりにデータ型ストアを使用します。ドキュメントはかなり優れています(他の人気のあるフレームワークはスナップそしてイェソド)。
また、最終的には学ぶべき概念(モナドの概念など)がたくさんあります。これは、脳が関連する抽象化のレベルに慣れているため、初めてモナドを学ぶよりも簡単です。これらの高レベルの概念とそれらがどのように組み合わさるかを学ぶための非常に良い概要は、タイプクラスペディア。
Applicative: Monad のようなインターフェースですが、それほど強力ではありません。すべての Monad は Applicative ですが、その逆はありません。これは、Applicative でありながら Monad ではない型がいくつかあるため便利です。また、Applicative 関数を使用して記述されたコードは、Monad 関数を使用して同等のコードを書くよりも構成しやすいことがよくあります。関数、応用関数、モノイドHaskell ガイドから学びましょう。
折りたたみ可能、通過可能: リストの多くの操作を抽象化した型クラス。同じ関数を他のコンテナ型に適用できます。ハスケル ウィキの説明。
モノイド: モノイドは、ゼロ (または空) の値と、 およびと
<>
なる 2 つのモノイドを結合する演算を持つ型です。これらは恒等法則と結合法則と呼ばれます。数値など、多くの型は および となるモノイドです。これは多くの状況で役立ちます。x <> mempty = mempty <> x = x
x <> (y <> z) = (x <> y) <> z
mempty = 0
<> = +
矢印: 矢印は、入力を受け取り、出力を返す計算を表す方法です。関数は矢印の最も基本的なタイプですが、他にも多くのタイプがあります。ライブラリには、矢印を操作するための非常に便利な関数も多数あります。これらは、単純な古い Haskell 関数で使用するだけでも非常に便利です。
配列: Haskell のさまざまな可変/不変配列。
ST モナド: モナドの外側では純粋なまま、非常に高速に実行される可変状態を持つコードを記述できます。詳細についてはリンクを参照してください。
FRP: 関数型リアクティブプログラミング。イベント、トリガー、入力、出力 (GUI など) を処理する新しい実験的なコード記述方法です。ただし、これについてはあまり詳しくありません。ポール・フダックのヤンパについての講演良いスタートです。
注目すべき新しい言語機能がたくさんあります。ここではそれらをリストアップします。Googleやハスケルウィキブック、haskellwiki.orgサイトとghc ドキュメント。
- マルチパラメータ型クラス/関数依存性
- タイプファミリー
- 存在量化された型
- ファントムタイプ
- ガッツ
- その他...
Haskellの多くはカテゴリー理論なので、調べてみるのもいいかもしれません。良い出発点はコンピュータ科学者のためのカテゴリー理論. 本を購入したくない場合は、著者の関連記事も素晴らしいです。
最後に、さまざまな Haskell ツールについて詳しく学びたいと思うでしょう。これには次のものが含まれます。
- ghc(およびそのすべての機能)
- 陰謀: Haskell パッケージ システム
- ダルクス: Haskell で書かれた分散バージョン管理システム。Haskell プログラムで非常に人気があります。
- ハドック: Haskell 自動ドキュメント生成ツール
これらすべての新しいライブラリと概念を学ぶと同時に、Haskellで中規模のプロジェクトを書くことは非常に有益です。それはどんなものでも構いません(例えば、小さなゲーム、データアナライザー、ウェブサイトなど)。コンパイラ)。これに取り組むことで、今学んでいることの多くを応用できるようになります。このレベルに長く留まります(これが私のレベルです)。
専門家
この段階に到達するには何年もかかります (2009 年からこんにちは!) が、ここからは博士論文の執筆、新しい GHC 拡張機能の作成、新しい抽象化の考案が始まると思います。
ヘルプの取得
最後に、学習のどの段階でも、情報を得る場所は複数あります。これらは次のとおりです。
- #haskell irc チャンネル
- のメーリングリスト行われている議論を読むだけでも、サインアップする価値があります。非常に興味深い議論もあります。
- haskell.orgのホームページに記載されているその他の場所
結論
予想以上に長くなりましたが... とにかく、Haskell に習熟するのはとても良いことだと思っています。時間はかかりますが、それは主に、そうすることでまったく新しい考え方を学んでいるからです。Java を学んだ後に Ruby を学ぶのではなく、C を学んだ後に Java を学ぶようなものです。また、Haskell を学んだ結果、アイデアを抽象化する新しい方法を多く知るようになり、オブジェクト指向プログラミング スキルが向上していることに気づいています。