モノイドからドモルガン代数まで。 Haskellで抽象化を構築する

正規分布、ステートマシン、ハッシュテーブル、任意の述語、文字列、凸包、アフィン変換、構成ファイル、CSSスタイルに共通するものは何ですか? そして、整数、Haskellの型、任意のグラフ、代替ファンクター、行列、正規表現、統計サンプルを統合するものは何ですか? 最後に、ブール代数、電気回路、長方形テーブル、パイプや建物の断熱材、平面上の画像を何らかの方法で相互接続することは可能ですか? これらの質問に対する2つの重要な答えがあります。1)これらすべてのオブジェクトを扱うプログラマー、2)これらのオブジェクトは類似の代数構造を持っています。1つ目はモノイド、2つ目は半環、3つ目はドモルガン代数です。







プログラマーが自分自身で学習し、コンピューターにモノイド、ハーフリング、その他の構造の操作方法を教えると、私たち全員が簡単に作業できるようになります。 代数構造には一定の制限が課せられており、制限から一定の保証が続くためです。 これらの制限と保証はすべて 、構造のすべての代表に対して有効です。つまり、モノイド、半環、代数、したがって上記および他の多くのオブジェクトすべてを操作するためのユニバーサルツールボックスを構築することができます。 代数構造を定義した数学者の数を確認してください ! そして、それらには定理があり、プログラマにとって有用なもの、まだあまり良くないものもありますが、それらはすべて最高のプログラムライブラリのように信頼性があります!







準同型が構造内に構築されると、すべてがさらにきれいになります-構造を保持する変換。 準同型は、構造のあるオブジェクトから別のオブジェクトに「切り替える」ことを可能にします-リストから数字、グラフから行列、正規表現からグラフ、電気回路からブール式、またはこれらの回路のグラフィック画像へ! まあ、同型は一般的に歌です! プログラマーが数学を必要とせず、これらのすべての射-モルフィズムが単なるナンセンスであると信じている場合、彼は美しく信頼できるツールだけでなく、最も重要なことには、仕事の喜びの本質的な部分を奪います。







この記事では、de Morgan代数の例によって、代数的抽象化の構築方法、準同型性とそれらの代数を定義する方法、そしてもちろんこれを使用する方法を示します。







この記事は、型クラス、ファンクター、モノイドが何であるかを既に知っており、一般的にHaskellプログラミングとは何かをよく知っている人を対象としています。 一方、プログラミングで抽象化がどのように構築され、実際の問題にそれらをどのように適用できるかに興味がある人は誰でも興味を持ちます。







モノイドについて少し



モノイドは構成の抽象化です。 同様に、合成は関数型プログラミングの重要な概念です。 モノイドがここで頻繁に見られ、そのような重要な役割を果たすのはそのためです。 モノイドの使用の価値と豊かさについて多くのことが言われ、書かれています。 ここで、それらの主要なプロパティをリストします。これは、以降のプレゼンテーションで役立ちます。







定義



非常に単純な構造はモノイドと呼ばれます。これは、単一のニュートラル要素を持つ連想バイナリ操作が定義されるセットです。 操作の可換性は必須ではありませんが、ニュートラル要素はニュートラルでなければならず、第1オペランドと第2オペランドの両方である必要があります。







HaskellはMonoid



クラスを定義します。







 class Monoid a where mempty :: a mappend :: a -> a -> a
      
      





Data.Monoid



ライブラリは、 Sum



Product



First



Last



Endo



など、このクラスの便利なインスタンスを多数提供します。







モノイドの重要な特性は、中立要素の結合性と一意性です。 これらの制限により、任意の実行順序(並列を含む)でモノイド操作を一般化できます。







デュアルモノイド



任意のモノイドに対して、バイナリ演算が逆の順序で引数を取るデュアルモノイドを定義できます。







 > Dual [1,2,3] <> Dual [5,6] Dual { getDual = [5,6,1,2,3] }
      
      





畳み込みリンク



ツールが畳み込みでどれほど便利で普遍的であるかはよく知られています:一方では、コレクションを処理する多数の便利な汎用関数が畳み込みによって表現され、他方では、リスト、ツリー、および他の帰納的コレクションを折りたたむことができます。 多くのバンドルが定義されています。 コレクションを右側と左側の両方で折りたたむことができます。これは、結果(折り畳み関数の結合性に応じて)と計算の効率に影響する可能性があります。 空のコレクションの場合は、畳み込みの初期結果を入力するか、コレクションが空でないことが保証されている場合は、畳み込みなしで実行することにより、折りたたむことができます。 したがって、Haskell標準ライブラリとData.Foldable



ライブラリにData.Foldable



、非常に多くの異なる畳み込みがあります。







  foldr, foldl, foldr1, foldl1, foldl', foldl1'
      
      





モノイドへの畳み込みについて話している場合、モノイド動作の連想性と中立要素の存在の保証により、1つの関数で十分です。







 fold :: (Monoid m, Foldable t) => tm -> m
      
      





最も一般的に使用されるオプションは、畳み込みに使用する特定のモノイドを明示的に示すことです。







 foldMap :: (Monoid m, Foldable t) => (a -> m) -> ta -> m
      
      





コレクションがファンクターの場合、 foldMap



関数のfoldMap



は次のように指定できます。







 foldMap f = fold . fmap f
      
      





無料モノ​​イド



時々、モノイド間で「通過」する可能性があります。そのような変換は準同型と呼ばれることを思い出してください。 さらに、準同型を他のものに構築できるモノイドが存在します。 このようなモノイドはフリーと呼ばれ、リストはHaskellで役割を果たします。







自由構造は代数システムの特性を反映しますが、何も「計算」したり、データを変更したり、情報を失ったりしません。 ある意味では、それらは代数システムまたはカテゴリの要素を記述するための正式な言語であり、準同型はこの言語のインタープリターと見なすことができます。 このようなアナロジーは、将来的に私たちに役立つでしょう。







Haskellでのモノイドとその応用についての記事を読んでください:









代数デモーガン



多くのオブジェクトには、いくつかの合成方法があり、1つのモノイドはここではできません。 そのような方法が2つある場合、リング、ハーフリング、ラティス、およびさまざまな代数について説明します。 それらの基礎となる代数構造の共通性を示唆するいくつかの例を考えてみましょう。







ブール代数



ブール代数について私たちは何を知っていますか:









A \ウカフェベッド = V E E ベッドと \ク V E Eのベッド = \くさんベッドと  







電気抵抗の代数



抵抗から成り、回路要素の直列または並列接続を可能にする任意のバイポーラ電気回路を計算するタスクを見てみましょう。










All Articles