24

Learn You a Haskellを読んでいて、すでに applicative について説明しましたが、今はモノイドに取り組んでいます。両方を理解するのに問題はありませんが、実際には applicative が有用であることがわかりましたが、monoid はそうではありません。だから、Haskell について何かを理解していないと思います。

まず、 について言えば、Applicative「コンテナ」に対してさまざまなアクションを実行するための統一された構文のようなものを作成します。したがって、通常の関数を使用してMaybe、 、リスト、IO(モナドと言った方がいいでしょうか? モナドはまだわかりません)、関数に対してアクションを実行できます。

λ> :m + Control.Applicative
λ> (+) <$> (Just 10) <*> (Just 13)
Just 23
λ> (+) <$> [1..5] <*> [1..5]
[2,3,4,5,6,3,4,5,6,7,4,5,6,7,8,5,6,7,8,9,6,7,8,9,10]
λ> (++) <$> getLine <*> getLine
one line
 and another one
"one line and another one"
λ> (+) <$> (* 7) <*> (+ 7) $ 10
87

したがって、適用可能は抽象化です。私たちはそれがなくても生きていけると思いますが、いくつかのアイデアモードを明確に表現するのに役立ちます.

では、 を見てみましょうMonoid。それは抽象化でもあり、かなり単純なものでもあります。しかし、それは私たちを助けますか?本のすべての例について、物事を行うためのより明確な方法があることは明らかです。

λ> :m + Data.Monoid
λ> mempty :: [a]
[]
λ> [1..3] `mappend` [4..6]
[1,2,3,4,5,6]
λ> [1..3] ++ [4..6]
[1,2,3,4,5,6]
λ> mconcat [[1,2],[3,6],[9]]
[1,2,3,6,9]
λ> concat [[1,2],[3,6],[9]]
[1,2,3,6,9]
λ> getProduct $ Product 3 `mappend` Product 9
27
λ> 3 * 9
27
λ> getProduct $ Product 3 `mappend` Product 4 `mappend` Product 2
24
λ> product [3,4,2]
24
λ> getSum . mconcat . map Sum $ [1,2,3]
6
λ> sum [1..3]
6
λ> getAny . mconcat . map Any $ [False, False, False, True]
True
λ> or [False, False, False, True]
True
λ> getAll . mconcat . map All $ [True, True, True]
True
λ> and [True, True, True]
True

そこで、いくつかのパターンに気付き、新しい型クラスを作成しました...いいですね、私は数学が好きです。しかし、実用的な観点からは、何のポイントMonoidですか? アイデアをよりよく表現するのにどのように役立ちますか?

4

4 に答える 4

32

Gabriel Gonzalez は、なぜ気にかけるべきか、そして本当に気にかけるべきなのかについて、彼のブログに素晴らしい情報を書いています。ここで読むことができます(また、これも参照してください)。

それは、API のスケーラビリティ、アーキテクチャ、および設計に関するものです。アイデアは、次のような「従来のアーキテクチャ」があるということです。

タイプ A のいくつかのコンポーネントを組み合わせて、タイプ B の「ネットワーク」または「トポロジ」を生成します。

この種の設計の問題点は、プログラムの規模が大きくなると、リファクタリングの際にも大規模になることです。

したがって、モジュール A を変更して設計またはドメインを改善したいので、そうします。あ、でもAに依存するモジュールB&Cが壊れてしまった。B を修正します。ここで、C を修正します。B も C の機能の一部を使用したため、B が再び壊れました。そして、私はこれを永遠に続けることができます.OOPを使用したことがあるなら、そうすることができます.

次に、Gabriel が「Haskell アーキテクチャ」と呼んでいるものがあります。

タイプ A のいくつかのコンポーネントを一緒に組み合わせて、同じタイプ A の新しいコンポーネントを生成し、その置換部分と特徴が区別できない

これにより、問題もエレガントに解決されます。基本的に、モジュールを重ねたり、拡張して特殊なモジュールを作成したりしないでください。
代わりに、結合します。

だから今、奨励されているのは、「私は複数の X を持っているので、それらの結合を表す型を作りましょう」のようなことを言う代わりに、「私は複数の X を持っているので、それらを X に結合しましょう」と言うことです。または簡単な英語で言うと、「最初に構成可能な型を作ろう」ということです。(モノイドが潜んでいるのを感じますか?)。

Web ページまたはアプリケーションのフォームを作成する必要があり、個人情報が必要なために作成したモジュール "Personal Information Form" があるとします。後で、「Change Picture Form」も必要であることがわかったので、すぐにそれを書きました。そして、それらを組み合わせたいと言うので、「個人情報と画像フォーム」モジュールを作りましょう。実際のスケーラブルなアプリケーションでは、これは手に負えなくなります。おそらくフォームではなく、デモンストレーションのために、「個人情報 & 写真の変更 & パスワードの変更 & ステータスの変更 & 友達の管理 & ウィッシュリストの管理 & ビュー設定の変更 & Please don't extend me more. &お願い&やめて!&やめて!!!!」モジュール。これは美しくない、この複雑さを API で管理する必要があります。ああ、何かを変更したい場合は、おそらく依存関係があります。そう..ええ..地獄へようこそ。

次に、他のオプションを見てみましょうが、最初にメリットを見てみましょう。

これらの抽象化は常に組み合わせ可能性を維持するため、無限に拡張できます。したがって、さらに抽象化を上に重ねる必要はありません。これが、Haskell を学ぶべき理由の 1 つです。つまり、フラットなアーキテクチャを構築する方法を学びます。

「個人情報フォーム」/「画像フォームの変更」モジュールを作成する代わりに、ここで何かを構成可能にすることができないか考えてみてください。「かたち」を作ればいいじゃないですか。もより抽象的になります。
次に、必要なものすべてに対して1つを作成し、それらを組み合わせて、他のものと同じように1つのフォームを作成することは理にかなっています.

したがって、2 つのフォームを取得して 1 つのフォームを取得するという鍵のおかげで、面倒で複雑なツリーを取得することはもうありません。だからForm -> Form -> Form。そして、すでにはっきりとわかるように、この署名は のインスタンスですmappend

代替案と従来のアーキテクチャは、おそらく次のようa -> b -> cになりc -> d -> eます...

さて、フォームの場合はそれほど難しくありません。課題は、これを実際のアプリケーションで使用することです。そのためには、できる限り多くのことを自問するだけです (ご覧のとおり、それは報われるからです): どうすればこの概念を構成可能にできますか? モノイドはそれを達成するための非常に簡単な方法なので (単純にしたいのですが)、最初に自問してみてください: この概念はどのようにモノイドなのか?

補足: ありがたいことに、Haskell は関数型言語 (継承なし) であるため、型を拡張することを非常に思いとどまらせます。ただし、何かの型を作成し、別の型を作成し、3 番目の型で両方の型をフィールドとして持つことは可能です。これが構成のためのものである場合は、回避できるかどうかを確認してください。

于 2014-10-07T15:15:34.973 に答える
10

いいですか、私は数学が好きです。しかし、実用的な観点から、モノイドのポイントは何ですか? アイデアをよりよく表現するのにどのように役立ちますか?

それはAPIです。シンプルなもの。以下をサポートするタイプの場合:

  • ゼロ要素を持つ
  • 追加操作がある

多くの型がこれらの操作をサポートしています。したがって、操作と API に名前を付けると、事実をより明確に把握するのに役立ちます。

API が優れているのは、コードと概念を再利用できるからです。より良い、より保守しやすいコードを意味します。

于 2014-10-07T08:36:02.373 に答える
6

Int要点は、 asにタグを付けるProductと、整数を乗算するという意図を表明することです。としてタグ付けすることでSum、一緒に追加できます。

mconcatその後、両方で同じものを使用できます。これは、特定のモノイドのような方法で要素を組み合わせながら、包含構造を折り畳むという考えを表現するFoldable場合などに使用されます。foldMap

于 2014-10-07T08:22:22.033 に答える