そのようなtypeclassは何ですか
9765 ワード
プログラミングでは、非常に頻繁に発生するパターンがあります.同じ型の2つのものをまとめて、その型の別のものを取得します.
そして、Haskellでは、我々はします.と呼ばれるタイプ
この記事では、typeclassと構造の両方をカバーします.
記事の最後までに、 モノイドとは 何が 定義済みのモノイドインスタンスを使う方法 あなた自身のインスタンスを定義する方法 モノイドはなぜ役に立つのか
Monoidのような数学用語では、定義を読む前に例を見るのが常に良いです.
したがって、Haskellでのモノイド様行動の3つの例を見てみましょう.
最初のオフ、リスト
そして最後に、
ご覧の通り、これら三つのことは同様に行動します.彼らは同じ法律に従っている.
さて、これらの法則がどれほど正確かを見てみましょう.
数学では、モノイドは、その集合上の要素(数字やブールなど)の集合と二値演算からなる構造体である
また、モノイドは以下の性質を満たす.
「何もしない」というアイデンティティ要素がある.より正式な用語では、モノイドの要素セットから任意の要素Xを取得し、その要素と同一要素を持つモノイドのバイナリ操作を使用すると、同じ要素- x - backを取得します.例えば、
結合このプロパティは、方程式内の括弧を並べ替えることで方程式の結果を変更しないことを保証します.例えば、
どのように、モノイドはハスケルに見えますか?
オンノート typeclassは関数として定義されません
前の例からデータ型でこれらのモノイドメソッドを使用してみましょう.
リストで動作します.
あなたが選択したバイナリ操作に応じて合計モノイド、製品のモノイド、および多くを持つことができます.GHCはどの操作を使いたいかわからない.
そのため、データ型をラップし、それらの型を使用するコンテキストに従って、モノイドインスタンスを作成する必要があります.
Haskellで独自のモノイドインスタンスを作成してみましょう.
まず、カスタムデータ型を作成します
半群がアイデンティティ要素のないモノイドであるので、これはそうです
では、次のインスタンスを定義しましょう
The
それは我々が必要とするすべてです
今、我々はGHCIでそれを再生することができます.
一般的に、モノイドは非常に高度な、興味深い、またはクールではありません.
しかし、彼らは本当に便利で、非常に簡単です.
あなたが現実のユースケースを捜しているならば、下記の更なる学習セクションはチャットフィルタを作って、選挙投票分布を計算するために単体の使用をカバーする資源を持ちます.
これは、クイック入門入門です
参考になるかもしれませんが、
私は、絶対的にHaskellについてTsodingのビデオを好みます.チャットのメッセージのフィルタを実装しながら、この1つで、彼はどのようにモノイドが役に立つことができるかを示しています.
Electoral vote distributions are monoids . ここでは、モノ世界が現実世界の問題を解決するために使用できる方法の別の例です.
Monoids in Haskell . 私はトピックで見つけることができる最高の紹介記事. あなたがHaskellについてより初心者指向の記事を読むことを望むならば、あなたは我々の会報(下記のフォームによって)を購読するために、または、我々について来て歓迎です.
ラッパータイプを実装するexclusive OR (XOR) . それの半群とモノイドのインスタンスを作成します. ラッパータイプを実装するlogical biconditional (XNOR) . それの半群とモノイドのインスタンスを作成します. インスタンスは1で作成します.と2 .モノイド法に続いてください?なぜ? ご存知かもしれませんが、半群はアイデンティティ要素のないモノイドです.半群であるが、モノイドではない構造の例を考え出せますか?
a -> a -> a
その周波数を考えると、それにはいくつかの有用な抽象化があるでしょう.そして、Haskellでは、我々はします.と呼ばれるタイプ
Monoid
それは、「一緒にものを壊す」という概念に関する要約です.同じ名前の数学的構造からインスピレーションを引き出します.この記事では、typeclassと構造の両方をカバーします.
記事の最後までに、
Monoid
Haskellのtypeclass ;Data.Monoid
; Monoid
; 直観力の構築
Monoidのような数学用語では、定義を読む前に例を見るのが常に良いです.
したがって、Haskellでのモノイド様行動の3つの例を見てみましょう.
最初のオフ、リスト
++
(連結)演算子.Prelude> [1,2] ++ [3, 4] -- You can concatenate lists.
[1,2,3,4]
Prelude> [1,2] ++ [] -- Concatenating an empty element to a list doesn't change the result.
[1,2]
Prelude> [] ++ [1,2]
[1,2]
Prelude> [1,2] ++ ([3,4] ++ [5,6]) -- It doesn't matter in which order you concatenate the lists, you get the same result either way.
[1,2,3,4,5,6]
Prelude> ([1,2] ++ [3,4]) ++ [5,6]
[1,2,3,4,5,6]
その後、+
演算子.Prelude> 1 + 2 -- You can sum two natural numbers together.
3
Prelude> 1 + 0 -- Adding a 0 doesn't change the sum.
1
Prelude> 0 + 1
1
Prelude> (1 + 2) + 3 -- It doesn't matter in which order you sum the numbers, you get the same result either way.
6
Prelude> 1 + (2 + 3)
6
(代わりに、*演算子を使用した場合もあります.そして最後に、
&&
演算子and
).Prelude> True && False -- You can join two booleans via &&.
False
Prelude> a = False
Prelude> a && True -- Adding && True doesn't impact the resulting boolean.
False
Prelude> True && a
False
Prelude> (True && True) && False -- It doesn't matter in which order you resolve the &&s, you get the same result either way.
False
Prelude> True && (True && False)
False
(あるいは、OR演算子を使ってブール演算を行いました.||
. その場合、結果を変更しない要素はFalse
.)ご覧の通り、これら三つのことは同様に行動します.彼らは同じ法律に従っている.
さて、これらの法則がどれほど正確かを見てみましょう.
どのようなモノイドですか?
数学では、モノイドは、その集合上の要素(数字やブールなど)の集合と二値演算からなる構造体である
+
or &&
).また、モノイドは以下の性質を満たす.
「何もしない」というアイデンティティ要素がある.より正式な用語では、モノイドの要素セットから任意の要素Xを取得し、その要素と同一要素を持つモノイドのバイナリ操作を使用すると、同じ要素- x - backを取得します.例えば、
1+0=1
, 2+0=0
など結合このプロパティは、方程式内の括弧を並べ替えることで方程式の結果を変更しないことを保証します.例えば、
(1+2)+3=1+(2+3)
. Haskellにおけるモノイド
どのように、モノイドはハスケルに見えますか?
:info
刑事は事件である.🕵️♂️Prelude> :info Monoid
type Monoid :: * -> Constraint
class Semigroup a => Monoid a where
mempty :: a
mappend :: a -> a -> a
mconcat :: [a] -> a
ご覧の通り.Monoid
Haskellでは、以下の3つのメソッドがあります.mempty
, mappend
, and mconcat
.mempty
はバイナリ操作と一緒に使用した場合の結果に影響しない値です.言い換えれば、それは、モノイドのアイデンティティ要素です.mappend
(or <>
) は2つのモノイドを一緒に置く関数です.つまり、モノイドのバイナリ操作です.mconcat
単体のリストを1つの値に減らす関数です.デフォルトではfoldr mappend mempty
. ほとんどのデータ型に対しては良いことで、定義する必要はありませんmconcat
インスタンスを定義するにはしかし、既定の実装が最適でないときには、関数の独自の実装を定義したい場合があります.オンノート
mappend
and <>
. <>
, これはSemigroup
, のスーパークラスMonoid
私が後で記事でカバーすること.すべての意図と目的のために、これらの機能は同じであるべきです.GHCの将来のリリースではmappend
will be removed , それで、あなたは使用を勧められます<>
.定義済みのモノイドインスタンスの使い方
前の例からデータ型でこれらのモノイドメソッドを使用してみましょう.
リストで動作します.
Prelude> [1,2] <> [3,4]
[1,2,3,4]
Prelude> mempty :: [a]
[]
Prelude> [1,2] <> mempty
[1,2]
しかし、あなたがしようとするならば1 <> 3
, GHCIでエラーが発生します.<interactive>:1:1: error:
• Ambiguous type variable 'a0' arising from a use of 'print'
...
🤔
これは1つのインスタンスがないからですMonoid
を参照してください.あなたが選択したバイナリ操作に応じて合計モノイド、製品のモノイド、および多くを持つことができます.GHCはどの操作を使いたいかわからない.
そのため、データ型をラップし、それらの型を使用するコンテキストに従って、モノイドインスタンスを作成する必要があります.
Data.Monoid
このようなラッパータイプを定義しますSum
, Product
, などnewtype Sum a = Sum { getSum :: a }
彼らがどのように働くか見ましょう.Prelude> import Data.Monoid
Prelude Data.Monoid> Sum 1 <> Sum 3
Sum {getSum = 4}
Prelude Data.Monoid> Product 2 <> Product 5
Product {getProduct = 10}
同様に、BooleansはAll
and Any
それらのために定義されたモノイド.Prelude Data.Monoid> All True <> All False
All {getAll = False}
Prelude Data.Monoid> Any True <> Any False
Any {getAny = True}
使えますmconcat
これらのモノイドのリストをまとめる.result = mconcat [Sum 4, Sum 6, Sum 8, mempty]
そして、アンラップされた結果を得るには、便利に呼ばれるレコード名を使用して、それらをアンラップすることができますgetX
.Prelude Data.Monoid> getSum result
18
Haskellでモノイドインスタンスを作成する方法
Haskellで独自のモノイドインスタンスを作成してみましょう.
まず、カスタムデータ型を作成します
Move
これはロボットが2次元場で動くよう指示する.data Move = Move Int Int deriving (Show, Eq)
データ型のモノイドインスタンスを作成するには、まず Semigroup
それのインスタンスSemigroup
のスーパークラスMonoid
( GHC 8.4以降).Prelude> :info Monoid
type Monoid :: * -> Constraint
class Semigroup a => Monoid a where
...
Prelude> :info Semigroup
type Semigroup :: * -> Constraint
class Semigroup a where
(<>) :: a -> a -> a
しかし、心配しないでください、ここに新しい何もありません.Aを作るSemigroup
インスタンスは、定義の丸い方法ですmappend
.半群がアイデンティティ要素のないモノイドであるので、これはそうです
mempty
). これは1つのメソッドを定義します.<>
– と同じmappend
, つの値を組み合わせるためのバイナリ演算.では、次のインスタンスを定義しましょう
Semigroup
. つの動きを追加するにはx
and y
値.instance Semigroup Move where
Move x1 y1 <> Move x2 y2 = Move (x1 + x2) (y1 + y2)
その後、我々は定義することができますMonoid
インスタンス.インスタンスを定義するには、mempty
だってmappend
は<>
.The
mempty
それは我々の場合、どこにも動かないことを意味します.Move 0 0
.instance Monoid Move where
mempty = Move 0 0
注:あなたのモノイドのインスタンスを作成しながら、モノイドの法則に従うように注意する必要があります.ハスケルproperty-based tests ) 私たちのモノイドのインスタンスが意味を確認する方法はありません.例えば、私たちは定義できましたmempty
あるMove 0 (-1)
, これはいくつかの奇妙な動作につながるでしょう.それは我々が必要とするすべてです
Move
一人称!🎉今、我々はGHCIでそれを再生することができます.
*Main> Move 3 4 <> Move 8 9
Move 11 13
*Main> Move 3 4 <> mempty
Move 3 4
また、mconcat
移動リストを折り畳む方法.*Main> stay = mempty :: Move
*Main> moves = [Move 1 2, Move (-3) 5, Move (-6) 3, stay, Move 2 3]
*Main> mconcat moves
Move (-6) 13
なぜモノイドが必要ですか?
一般的に、モノイドは非常に高度な、興味深い、またはクールではありません.
しかし、彼らは本当に便利で、非常に簡単です.
<>
は、多くの異なるタイプを連結するのに使用されて、基本的なビルディングブロックと考えられることができました.それはあなたがすべてのHaskellプロジェクトで会うという演算子です.あなたが現実のユースケースを捜しているならば、下記の更なる学習セクションはチャットフィルタを作って、選挙投票分布を計算するために単体の使用をカバーする資源を持ちます.
更なる学習
これは、クイック入門入門です
Monoid
Haskellのtypeclassうまくいけば、今、どのようなモノイドの法則は、どのようにHaskellでモノイドを使用する方法を定義し、どのようにMonoid
typeclass参考になるかもしれませんが、
私は、絶対的にHaskellについてTsodingのビデオを好みます.チャットのメッセージのフィルタを実装しながら、この1つで、彼はどのようにモノイドが役に立つことができるかを示しています.
Electoral vote distributions are monoids . ここでは、モノ世界が現実世界の問題を解決するために使用できる方法の別の例です.
Monoids in Haskell . 私はトピックで見つけることができる最高の紹介記事.
演習
Reference
この問題について(そのようなtypeclassは何ですか), 我々は、より多くの情報をここで見つけました https://dev.to/serokell/whats-that-typeclass-monoid-3g3nテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol