Haskellを使い始める


755

数日間、Haskellの関数型プログラミングパラダイムに頭を抱えました。私はチュートリアルを読んだり、スクリーンキャストを見てこれを行いましたが、実際には何も固執していないようです。さて、さまざまな命令型/オブジェクト指向言語(C、Java、PHPなど)を学ぶ上で、エクササイズは私にとって良い方法でした。しかし、Haskellで何ができるか本当にわからないので、利用できる新しい概念がたくさんあるので、どこから始めればよいのかわかりません。

では、どのようにしてHaskellを学びましたか?本当に「氷を砕く」理由は何ですか?また、演習を始めるための良いアイデアはありますか?


回答:


2476

このガイドは、絶対的な初心者から専門家まで、Haskellでのスキルレベルに基づいて注文します。このプロセスには数か月(数年)かかるため、かなり時間がかかることに注意してください。

全くの初心者

第一に、Haskellは十分なスキルがあれば何でもできます。これは非常に高速で(私の経験ではCおよびC ++の背後にあります)、シミュレーションからサーバー、GUI、およびWebアプリケーションまで、あらゆる用途に使用できます。

ただし、Haskellの初心者向けには、他の問題よりも書きやすい問題がいくつかあります。数学的問題とリスト処理プログラムは、Haskellの最も基本的な知識を書くだけでよいので、これに適した候補です。

まず、ハスケルの非常に基本を学ぶにはいくつかの良いガイドがある幸せは、Haskellのチュートリアルを学ぶとの最初の6章あなたにハスケルを学びます。これらを読みながら、あなたが知っていることで簡単な問題を解決することも非常に良い考えです。

もう1つの優れたリソースは、第一原理からのHaskellプログラミング、Haskellでのプログラミングです。どちらも各章の演習が付属しているため、最後の数ページで学んだ内容と一致する小さな単純な問題があります。

試す問題の良いリストは、haskell 99の問題のページです。これらは非常に基本的なものから始まり、次第に難しくなります。再帰や高次関数のスキルを練習できるので、これらの多くを実行することは非常に良い練習です。ランダム性を必要とする問題はスキップすることをお勧めします。これは、Haskellでは少し難しいためです。QuickCheckを使用してソリューションをテストする場合は、このSOの質問を確認してください(下の「中間」を参照)。

それらのいくつかを実行したら、プロジェクトオイラー問題のいくつかを実行することに進むことができます。これらは、何人の人がそれらを完了したかによって並べ替えられており、これは難易度のかなり良い指標です。これらは以前の問題よりもロジックとHaskellをテストしますが、最初のいくつかはまだ実行できるはずです。これらの問題に対するHaskellの大きな利点は、整数のサイズに制限がないことです。これらの問題のいくつかを完了するには、Haskellについても学ぶことの第7章と第8章を読むことも役立つでしょう。

初心者

その後、再帰関数と高次関数をかなりうまく扱えるようになるので、実世界の問題をいくつか始めてみるのがよいでしょう。開始するのに非常に適した場所は、Real World Haskellです(オンラインブック、ハードコピーも購入できます)。最初のいくつかの章は、関数型プログラミングをやったことがなく、再帰を使用したことがない人には、あまりにも早く導入しすぎたことがわかりました。ただし、以前の問題を実行することから得ていたであろう慣習があれば、完全に理解できるはずです。

本の問題に取り組むことは、Haskellで抽象化を管理し、再利用可能なコンポーネントを構築する方法を学ぶのに最適な方法です。通常のoo抽象化メソッド(ooクラス)はHaskellに表示されないため、これはオブジェクト指向(oo)プログラミングに慣れている人々にとって重要です(Haskellには型クラスがありますが、ooクラスとはooインターフェースのように非常に異なります)。後の章で使用される多くの新しいアイデアが紹介されているので、章をスキップするのは良い考えではないと思います。

しばらくすると、14章に行きます。恐ろしいモナドの章(dum dum dummmm)。Haskellを学ぶほとんどの人は、概念がいかに抽象的なかにより、モナドを理解するのに苦労しています。モナドが関数型プログラミングにあるのと同じくらい抽象的な他の言語の概念は思いつきません。モナドを使用すると、多くのアイデア(IO操作、失敗する可能性のある計算、解析など)を1つのアイデアに統合できます。モナドの章を読んだ後で本当に理解できなくてもがっかりしないでください。モナドについてのさまざまな説明を読むのが便利だと思いました。それぞれが問題について新しい見方をします。モナドチュートリアルの非常に優れたリストを次に示します。All About Monadsを強くお勧めしますが、他のものも良いです。

また、コンセプトが本当に浸透するまでにはしばらく時間がかかります。これは、使用を通じて発生しますが、時間によっても発生します。私は時々問題で寝ることが何よりも役立つことに気づきます!結局、アイデアがクリックされ、実際には信じられないほど単純な概念を理解するのになぜ苦労したのかと不思議に思うでしょう。これが起こるとき、それは素晴らしいです、そして、それが起こるとき、あなたはHaskellがあなたのお気に入りの命令型プログラミング言語であることに気付くかもしれません:)

Haskellの型システムを完全に理解していることを確認するには、20の中間的なhaskellの演習を解く必要があります。「furry」や「banana」などの関数の楽しい名前を使用した演習は、基本的な関数型プログラミングの概念をまだ理解していない場合に、それらをよく理解するのに役立ちます。矢、ユニコーン、ソーセージ、毛皮で覆われたバナナで覆われたたくさんの紙で夜を過ごすのに最適な方法。

中級

モナドを理解したら、初心者のHaskellプログラマーから中級のhaskellerに移行したと思います。それでは、ここからどこへ行くのでしょうか?私が最初に推奨するのは(モナドを学習していない場合)、リーダー、ライター、ステートなど、さまざまな種類のモナドです。繰り返しますが、現実世界のHaskellとモナドについてのすべては、これを非常にカバーしています。モナド変換を学ぶモナドトレーニングを完了するには、必須です。これらにより、異なるタイプのモナド(ReaderとStateモナドなど)を1つに組み合わせることができます。これは最初は役に立たないように思えるかもしれませんが、しばらく使用した後は、それらなしでどのように生活していたのか不思議に思うでしょう。

これで、必要に応じて、実際のHaskellブックを完成させることができます。モナドがパットダウンしている限り、チャプターをスキップすることは今や本当に重要ではありません。興味のあるものを選択してください。

あなたが今持っている知識があれば、cabalのほとんどのパッケージ(少なくとも文書化されたもの)だけでなく、Haskellに付属するほとんどのライブラリを使用できるはずです。試してみる興味深いライブラリのリストは次のとおりです。

  • Parsec:プログラムとテキストを解析します。正規表現を使用するよりもはるかに優れています。優れたドキュメントには、実際のHaskellの章もあります。

  • QuickCheck:とてもクールなテストプログラム。あなたがすることは、常に真でなければならない述語を書くことです(例えばlength (reverse lst) == length lst)。次に、述語QuickCheckを渡すと、多数のランダムな値(この場合はリスト)が生成され、すべての結果に対して述語が真であることをテストします。オンラインマニュアルもご覧ください。

  • HUnit:Haskellでのユニットテスト。

  • gtk2hs:Haskellで最も人気のあるGUIフレームワークで、Haskellでgtkアプリケーションを記述できます。

  • happstack:HaskellのWeb開発フレームワーク。データベースを使用せず、データ型ストアを使用します。かなり良いドキュメントです(他の一般的なフレームワークはsnapyesodです)。

また、最終的に学ぶ必要のある多くの概念(モナド概念など)があります。これは、モナドを初めて学ぶよりも簡単です。あなたの脳は、関与する抽象化のレベルを扱うことに慣れているからです。これらの高レベルの概念とそれらがどのように適合するかについて学ぶための非常に優れた概要は、Typeclassopediaです。

  • 適用:モナドのようなインターフェイスですが、それほど強力ではありません。すべてのモナドは適用可能ですが、その逆はありません。適用可能でモナドではないタイプがいくつかあるため、これは便利です。また、多くの場合、Applicative関数を使用して記述されたコードは、Monad関数を使用して同等のコードを記述するよりも構成可能です。参照ファンクタ、ApplicativeのファンクタとモノイドからはあなたのHaskellのガイドを学びます。

  • 折り畳み式Traversableの:型クラスリストの操作の抽象多く、これと同じ機能が他のコンテナ型に適用することができています。haskell wikiの説明も参照してください。

  • モノイド:Aモノイドは表記、ゼロ(又はmempty)値、及び動作を有するタイプであり<>、2つのモノイドを結合し、そのようにx <> mempty = mempty <> x = xx <> (y <> z) = (x <> y) <> z。これらは、アイデンティティおよび関連性の法則と呼ばれます。多くのタイプは、数値などのモノイドで、とmempty = 0を使用し<> = +ます。これは多くの状況で役立ちます。

  • 矢印:矢印は、入力を受け取って出力を返す計算を表す方法です。関数は最も基本的なタイプの矢印ですが、他にも多くのタイプがあります。このライブラリには、矢印を操作するための非常に便利な関数も多数あります。これらは、単純な古いHaskell関数でのみ使用した場合でも非常に便利です。

  • 配列:Haskellのさまざまな可変/不変の配列。

  • STモナド:モナドの外では純粋なまま、非常に高速に実行される変更可能な状態でコードを記述できます。詳細については、リンクを参照してください。

  • FRP:関数型リアクティブプログラミング。イベント、トリガー、入力、出力(GUIなど)を処理する新しい実験的な方法でコードを記述します。私はこれについてはあまり知りません。Paul Hudakのヤンパについての話は良いスタートです。

あなたが見ておくべき新しい言語機能がたくさんあります。私はそれらをリストアップします、あなたはグーグル、haskell wikibook、haskellwiki.orgサイトとghcドキュメンテーションからそれらに関する多くの情報を見つけることができます。

  • マルチパラメータタイプのクラス/機能の依存関係
  • タイプファミリー
  • 実存的に定量化されたタイプ
  • ファントムタイプ
  • ガッツ
  • その他...

Haskellの多くはカテゴリ理論に基づいているので、それを調べたいと思うかもしれません。良い出発点は、コンピュータサイエンティストのカテゴリ理論です。もし本を買いたくないなら、著者の関連記事も素晴らしいです。

最後に、さまざまなHaskellツールについて詳しく学びたいと思います。これらには以下が含まれます:

  • ghc(およびそのすべての機能)
  • cabal:Haskellパッケージシステム
  • darcs:Haskellで書かれた分散バージョン管理システム。Haskellプログラムで非常に人気があります。
  • haddock:Haskell自動ドキュメントジェネレーター

これらのすべての新しいライブラリと概念を学びながら、Haskellで中規模のプロジェクトを書くことは非常に役立ちます。どんなものでもかまいません(小さなゲーム、データアナライザ、ウェブサイト、コンパイラなど)。これに取り組むことで、今学んでいる多くのことを適用することができます。あなたはこのレベルで年齢を保ちます(これが私がいるところです)。

専門家

この段階に達するには数年かかります(2009年からこんにちは!)。ここから、phd論文、新しいghc拡張機能を書き始め、新しい抽象化を思い付くようになると思います。

困ったときは

最後に、学習のどの段階でも、情報を入手するための複数の場所があります。これらは:

  • #haskell ircチャンネル
  • メーリングリスト。これらは行われる議論を読むためだけにサインアップする価値があります-いくつかは非常に興味深いです。
  • haskell.orgホームページにリストされている他の場所

結論

まあ、これは予想よりも長くなりました...とにかく、Haskellに習熟することは非常に良い考えだと思います。時間がかかりますが、それは主に新しい考え方を学んでいるからです。これは、Javaを学習した後にRubyを学習するのではなく、Cを学習した後にJavaを学習するのと同じです。


35
やった矢!最初にモナドに脳を形作らせ、次に頭の上に立ってコモナドについて考え、次に矢印を取得するために同時に両方を行います:)タイプレベルで開くことができるHaskellには多くの表現力がありますプログラミングも。
ephemient 2009

13
@nanothief Monadはより強力ですが、構成も少なくなります...多くの人々は、よりクリーンなApplicativeコードで逃れることができたモナドを使用します。sであるもののほとんどFunctorMonads ですが、使用しても十分では>>=ありません。後者を使用すると、コードがはるかに単純になるためです。returnfmap
トムクロケット

8
@pelotom、私はtypeclassopediaリンクと、そのセクションにApplicativeを使用するより良い理由を追加し、Functorセクションを削除しました。ほとんどの教材(RWHを含む)ではモナドに重点が置かれているため、モナドとアプリケーションの概念を正しい順序で取得するのは困難です。一方、haskellのチュートリアルを教えることは、私が最初に回答を書いて以来(約2年:O)、長い道のりを歩んできました。また、モナドの前にApplicativeを教えています。
デビッド・ミアーニ、

2
素晴らしいアドバイス。私はこれを1年以上前に開始し、中級段階のほとんどの段階にいます。フィードバック:RWHのモナドチャプター(14章)は十分に説明されていません。RWHのオンライン版を読むと、章を支援するクラウドソーシングされたコメントが含まれるため、有益です。FWIW、あなたはモナドを発明したかもしれませんが、私にとって最も効果的なモナドチュートリアルでした。
トム

6
@tomf:ありがとう!私はいつもこの答えが上手くいっていることに驚いていました-私が書いてから5年近くになりますが、それでもまだ強力です。少し古くなっているので、すぐに更新する必要があります。レンズ、パイプ、制約の種類、haskellプラットフォーム、タイプレベル番号については触れられていません。これは、これが書かれて以来、かなり大きな新しいトピックです。RWHはもはや良くない、それは長い間更新されておらず、多くの例はコンパイルされていません。とにかくそれがあなたにとって役に立ったとうれしいです。
David Miani、2014年

180

私の同僚の中には、Learn You a Haskell for Great Good!

チュートリアルは、命令型プログラミング言語の経験はあるが、関数型言語でプログラミングしたことがない人を対象としています。

そして、ここでも答えを確認してください


27
私はこれを2番目にします。:それは明らかではありませんので、また、ここではチュートリアルのダウンロード可能なPDF版へのリンクがありますlearnyouahaskell.com/learnyouahaskell.pdfウェブデザインは素晴らしいですが、私はあまりにも地下鉄のためのコピーを持っているのが好き。
テレマコス

8
私はこれから始めましたが、私の意見では、直接Real World Haskellに行くべきです。違いは、K&RからCを学習するようなものです。「C for dummies」はシンプルにしようとしていますが、そのアプローチでは重要なものを見逃しています。Haskellを「命令的な方法」で学ぼうとするよりも、事実を正直に理解する方が良いと思います。
John Smith、

7
私はこれが大好きで、これとReal World Haskellに多くの時間を費やしてきました。IMO、「Learn You a Haskell」は、Real World Haskellよりも深い洞察を提供しますが、どちらも優れたリソースです。
チャーリーフラワー

7
@ abababa22 LYAHを最初に読んでからRWHに行くのが一番だと思います。LYAHはHaskellだけを教えているわけではありません。関数型プログラミングを教えます。問題を解決するとき、あなたは機能的な方法で考え始めます。明らかに、大規模なアプリケーションを作成するにはLYAHだけでは十分ではありませんが、それはあなたの心を正しい方向に曲げます。あなたが命令的なバックグラウンドから来ているなら、これが最善の方法です、IMO
Abdulsattar Mohammed

4
@Telemachus注意:PDFは最終版ではなく、少なくとも最後の章はありません。
sdcvvc 2013年

103

これがオンラインで読める良い本です:Real World Haskell

私が行ったHaskellプログラムのほとんどは、Project Eulerの問題を解決するためのものです。

少し前に読んだアドバイスの1つは、(理論的には)解決方法を知っている単純な問題の標準セットがあり、新しい言語を学習しようとするときはいつでも、その言語でそれらの問題を実装することです。


2
私の経験では、Real World Haskellは素晴らしいです。第5章に到達するまでは、それ以降はお勧めしません。
MasterMastic 14

なぜ@MasterMasticなのですか?5章以降の問題は何ですか?お金を使う前に知りたいのですが。
Jay Blanchard

@JayBlanchard第5章では、ライブラリの具体的な例の取得を開始します。これは素晴らしいことですが、彼らは何をするのかを教えてくれますが、理由を完全に説明していませんし、まったく明確ではありません。かなりの魔法の16進リテラル。あなたはただの動きを経験しているだけです。それは私にとっては最大の問題ではありませんでした。最大の問題は、本がそのようなハードで長い例に大きく依存していることです(章全体を超えるほど長い)。読みたい部分だけはほとんど読めません。私は素晴らしい作家であり、驚くべき知識ですが、実行力は非常に低いと思います。
MasterMastic 2014


69

他の人の答えを追加するために-コーディングするとき(たとえば、プロジェクトのオイラー問題を解決するとき)に役立つ便利な方法が1つあります 。Hoogleです。コマンドラインインターフェイスまたはWebインターフェイスのいずれかを使用できます

コマンドライン

Haskellプラットフォームをインストールしたら、必ず cabal install hoogle

Hoogleの使用例:

関数がf x = 3 * x + 1あり(5 :: Int)、それをに適用し、次にそれを結果およびその結果などに適用して、これらの値の無限リストを取得する場合。あなたはあなたを支援する機能がすでに存在しているのではないかと疑っています(特にあなたのためではfありません)。

その関数は(a -> a) -> a -> [a]、それが取るf 5場合または取る場合に型にa -> (a -> a) -> [a]なります5 f(関数はInts だけではなく、一般的な型用であると想定しています)

$ hoogle "a -> (a -> a) -> [a]"
Prelude iterate :: (a -> a) -> a -> [a]

うん、必要な関数がすでに存在し、それが呼び出されiterateます。あなたはそれを使うiterate func 5

ウェブインターフェース

同じ例の結果はここにあります


Hoogleに必要なものを尋ねる方法を理解すれば、必要なものに対応する標準ライブラリ関数を見つけるのが非常に簡単になります。
ankh-morpork 2015

57

グラハム・ハットンのHaskellでプログラミングは簡潔で、かなり徹底的であり、Haskellでの彼の長年の指導は本当に示しています。どこから行くかに関係なく、ほとんどの場合、私が最初に人々に勧めるのはこのことです。

特に、第8章(「関数パーサー」)は、モナドの処理を開始するために必要な実際の土台を提供します。これから始めるのが断然最善の場所だと思います。次に、オールアバウトモナドが続きます。(ただし、その章に関しては、Webサイトのエラッタに注意してくださいdo。特別な助けがなければフォームを使用することはできません。最初に型クラスについて学び、その問題を自分で解決したい場合があります。)

これがHaskellの初心者に強調されることはめったにありませんが、モナドの使用だけでなく、独自のモナドの構築についてもかなり早い段階で学ぶ価値があります。それは難しくはなく、カスタマイズされたものは多くのタスクをかなり簡単にすることができます。


5
これは完全に評価されていない本(および答え)です。関数パーサーの章の後にIOの章が続きますが、どちらもモナドについては触れていませんが、本当にエレガントな教育的アプローチとして輝いています。
michiakig


31

#haskell ircチャンネルに参加して質問することをお勧めします。それが私がハスケルを学んだ方法です。上記のようにReal World Haskellを使用すると、質問に対するリアルタイムの回答が非常に役立ちます。#haskellの多くの賢い人々が楽しみと利益のためにHaskellを書いているので、たくさんの良い情報を得ることができます。それを試してみてください!


5
+1-明確にするために:ircチャネルだけで学習しないでください。同様に、「haskellプログラムを書くにはどうすればいいですか?数値を追加するにはどうしたらいいですか?」
代替

irc freenodeに加えて、最近Discordチャットでのhaskellに関する活発な議論も増えています。
TruthAdjuster 2018


19

さらに紹介として、Yet Another Haskellチュートリアルをお勧めします。

私の知る限り、私を大いに助け、他の回答で言及されていない別の優れた学習リソース(おそらく中級レベル)は、モナドリーダー(問題)にあるBrent YorgeyのTypeclassopediaです13)

非常にアクセスしやすいスタイルで記述されており、(他の多くのものの中でも)次の導入に関するアドバイスが含まれています。

専門家のハスケルハッカーの知恵には2つの鍵があります。

  1. タイプを理解する。

  2. 多くの例に精通することで、各型クラスと他の型クラスとの関係について深い直感を得ることができます。

モナドリーダー自体は、(Haskellプログラマーだけでなく)関数型プログラマーにとって絶対的な宝庫です。


14

簡単なプログラムを書いてみてください。

おそらく、さまざまな教科書でサンプルタスクを見つけることができます。

Haskell / FPの教科書にこだわるのはお勧めしません。単純に、計算、文字列操作、ファイルアクセスなどを試してみてください。

私がダースを解決した後、私は氷を壊しました:)

その後、haskellは無限であり、その多くがあるため、高度な概念(Monads、Arrows、IO、再帰的データ構造)についてたくさん読んでください。


14

何よりもまず、Haskellの機能を例で実現することが最善の方法だと思います。

http://en.wikipedia.org/wiki/Haskell_98_features

これはモナドや矢印を含むトリッキーな型クラスです

http://www.haskell.org/haskellwiki/Typeclassopedia

現実世界の問題とより大きなプロジェクトの場合は、GHC(最も使用されるコンパイラ)、Hackage(libraryDB)、Cabal(ビルドシステム)、darcs(別のビルドシステム)のタグを覚えておいてください。

統合システムにより時間を節約できます:http : //hackage.haskell.org/platform/

このシステムのパッケージデータベース:http : //hackage.haskell.org/

GHCコンパイラーのWiki:http : //www.haskell.org/haskellwiki/GHC

Haskell_98_featuresとTypeclassopediaの後で、あなたはすでにそれらについてのドキュメントを自分で見つけて読むことができると思います

ちなみに、将来のHaskell標準の一部になる可能性があるGHCの言語拡張機能をテストすることもできます。

これがHaskellを学ぶための私の最良の方法です。お役に立てれば幸いです。


13

まずBONUSのチュートリアルを読み、次にReal World Haskell(オンラインで無料)を読むことをお勧めします。irc.freenode.comの#Haskell IRCチャネルに参加して、質問してください。これらの人々はまったくの初心者に優しく、長い間私を助けてくれました。また、ここSOは、把握できないことについてサポートを受けるのに最適な場所です。落胆しないようにしてください。クリックすると、あなたの心は吹き飛ばされます。

BONUSのチュートリアルは、あなたを盛り上げ、Real World Haskellがもたらすスリルに乗る準備をします。私はあなたの幸運を祈ります!


12

命令型/ OO言語の経験しかない場合は、より一般的な関数型言語を踏み台として使用することをお勧めします。Haskellは本当に異なっており、どこに行くにも多くの異なる概念を理解する必要があります。まず、MLスタイルの言語(F#など)に取り組むことをお勧めします。


Elmは、これらの代替品の中で最も近く、より使いやすく、初心者に優しいかもしれません...
Pedro Rolo

1
F#のような一時的なルートを通過することに同意しません。私にとっては、ウォッカを飲むのと同じです。その方が苦痛ですが、喜びもあります。一時的なルートですが、混乱を招くだけです。
TruthAdjuster 2018

10

最初の答えはとても良いものです。エキスパートレベルに到達するには、一部のエキスパートと博士号を取得する必要があります。

Haskellのページhttp://haskell.orgにアクセスすることをお勧めします。そこでは、Haskellコミュニティによって承認された、Haskellの最新の資料への多くの資料と参照がたくさんあります。


2
申し訳ありませんが、ここでPhD引数を使用することは、優れたシェフになるには300ドルの包丁が必要だと言っているようなものです。ハスケルの父であるサイモンペイトンジョーンズでさえ、博士号はありません。実践と粘り強さが、ここと他の分野の両方で専門知識につながります。
Petras Purlys 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.