私はしばらくの間Scala(そして拡張的にはHaskell)を研究していて、それらの型システムと機能パラダイムに完全にとらわれています。ごく最近、私は「タイプレベルプログラミング」に出くわし、ファンクターや他の聞いたことのないものに引きずり込まれました(モナドは神秘的な性質のものであると知っていましたが、何を利用すればよいかわかりませんでした)。それ!)。私はHaskellで概念を研究し(そして、その型システムと型推論機能に魅了されました)、純粋に技術的なレベルで型がFunctor、PointedFunctor、ApplicativeFunctor、またはMonoidであることが何を意味するのかをしっかりと理解しています(私はまだモナドが技術レベルでさえ何であるかを知りません)しかし私は mいくつかの概念の適切な分類が取得されていることを除いて、これらすべての用途が見当たらないので、ばかみたいに感じます(?)。これらは何に役立ちますか?なぜ人生をそんなに複雑にするのですか?なぜこれらのものを研究し、それらをさまざまなクラスに分類するのですか?
5 に答える
なぜ人生をそんなに複雑にするのですか?
それらはすべて、人生をよりシンプルにするためにあります!
第一に、それらは私たちが書くコードをよりクリーンで明確にします。
第二に、真に新しい言語機能を追加することなく、表現力を高めます。たとえば、Monadsを使用すると、標準の構文を使用して複雑な計算コンテキストを表現できます。Functorsを使用すると、データ構造について標準的な方法で考えてプログラミングできます。ApplicativeFunctorsを使用すると、効果的または複雑な計算コンテキストを、単純なデータを処理するのと同じように簡単に処理できます。純粋なデータの外で機能パラダイムをきれいに使用します。
それらはすべて、コードの再利用を助け、物事についての標準的な考え方を私たちに与えるので、お互いのコードを理解するのに役立ちます。
あなたがそれらに慣れたら、あなたはそれらなしではやりたくないでしょう!
それらはすべて抽象化です。例えば。モノイドは、ゼロ要素と加算をサポートするものです (結合する必要があります)。例としては、整数、リスト、文字列などがあります。これらすべての異なる型に対して単一の共通の「インターフェース」を持つことはかなり良いと思います。
では、なぜそれらが役立つのでしょうか。たとえば、すべてのモノイドに対して一般的な合計関数を作成できます。文字列や整数などの関数を記述する代わりに、汎用関数を 1 つだけ記述します。とても便利だと思います。
最初に質問する必要があります:ファンクタ、モナドとは何ですか ... . これらの概念が (意味する) ものであることがわかっていない限り、それらの用途について話すことは困難です。
これらの概念は圏論から来ています。それらは、数学 (およびその結果関数型プログラミング) の多くのオブジェクトがいくつかの共通の抽象的なプロパティを共有しているという事実から生じます。これらのプロパティを知って理解したら、それらを使用して、非常に大量のタスクで再利用可能な非常に汎用的なコードを記述できます。
例を挙げると:誰もが関数を知っています
map :: (a -> b) -> ([a] -> [b])
関数 from a
tob
を使用すると、リストで機能する関数を作成できます[a]
。ファンクターはこの概念の一般化です。この方法でマッピングできる (そしてファンクターの法則を保持する) ものはすべて、ファンクターと呼ばれます。そうFunctor
宣言する
fmap :: Functor f => (a -> b) -> (f a -> f b)
リストの場合はf
となり[]
ます。を使用fmap
すると、リスト (ここでは に等しいmap
) だけでなく、Maybe
s、さまざまなコレクション、ツリー、さらには関数にもマップできます。
こちらもご覧ください
さらに、モナドは「神秘的」ではないことを指摘したいと思います。特にコンテナのようなモナド(リスト、多分、アイデンティティ)は非常に理解しやすいです。これらはファンクターに似ていますが、ひねりがあります。fmap
元のファンクターの「形状」(リスト内の要素の数など)の使用は保持されます。たとえば、のfmap
ようなものを実装するために使用することはできませんfilter
。そのため、モナドには「bind」(Haskellでは(>>=)
)と呼ばれるこの種の機能がありますが、魔法ではありません(たとえば、リストの場合、古き良きものと同じconcatMap
です)。さらに、モナドにはreturn
単一の値をラップする機能があります。
現在、「コンテナのような」ものではない他の多くのものがモナドです。「保存された計算」(Cont
継続モナドの場合)を操作できるモナドがあります。それらは、ある種の「追加のコンテキスト」を提供( Reader
)、収集(Writer
)、または保持( )することができます。State
非常に有用な「コンテキスト」は、「その他の世界の状態」であり、IO
。その場合、型システム(特にポリモーフィズムと型クラスによって課せられる制限)は、不要な相互作用を防ぎ、特定の計算順序(怠惰な言語では簡単ではありません)を強制することができるので、汚いハックや言語の逆戻りは必要ありません-純粋な言語でIOを行うためのドア。これは一種の魔法だと考える人もいますが、これは型システムの巧妙な使用法であり、モナドだけがこの問題の解決策ではありません(たとえば、Cleanという言語はこれに「一意性型」を使用します)。
「これは何の役に立つの?」ああ!それらを使用して FizzBuzz を作成できます: http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html