2

空でないモノイドを選択する関数が必要です。リストの場合、これは次の動作を意味します。

> [1] `mor` []
[1]
> [1] `mor` [2]
[1]
> [] `mor` [2]
[2]

今、私は実際にそれを実装しましたが、一種の一般的なケースのように見えるため、標準的な代替手段が存在するかどうか疑問に思っています. 残念ながら、Hoogle は役に立ちません。

これが私の実装です:

mor :: (Eq a, Monoid a) => a -> a -> a
mor a b = if a /= mempty then a else b
4

3 に答える 3

4

リストに要素が 1 つしか含まれていない場合、それらは に同形Maybeであり、そのために「最初の空でない」モノイドFirstfrom がありData.Monoidます。Maybe aこれは値のラッパーであり、最初の値をmappend返します。Just

import Data.Monoid
main = do
    print $ (First $ Just 'a') <> (First $ Just 'b')
    print $ (First $ Just 'a') <> (First Nothing)
    print $ (First Nothing)    <> (First $ Just 'b')
    print $ (First Nothing)    <> (First Nothing :: First Char)

==> Output:
First {getFirst = Just 'a'}
First {getFirst = Just 'a'}
First {getFirst = Just 'b'}
First {getFirst = Nothing}

変換[a] -> Maybe aは を使用して達成されData.Maybe.listToMaybeます。

余談ですが、これはラップされた型の型クラスを制約しません。あなたの質問では、Eqと等しいかどうかを比較するインスタンスが必要memptyです。Maybeもちろん、これには型を持つという代償が伴います。

于 2012-11-28T23:03:10.090 に答える
3

[これは回答ではなく長いコメントです]

私のコメントで、「モノイドには内省の概念がない」と言ったとき、モノイドに対して分析(パターンマッチング、等値、<、>など)を実行できないことを意味しました。もちろん、これは明らかです。モノイドの API は、ユニット(mempty) と、2 つのモノダイヤルを取り、1 つを返す操作mappend (より抽象的には <>) だけです。型のmappendの定義はケース分析を自由に使用できますが、後でモノイドのものでできることは Monoid API を使用することだけです。

Haskell コミュニティでは、何かを発明することを避け、代わりに数学とコンピューター サイエンス (関数型プログラミングの歴史を含む) のオブジェクトを使用することを好むというのは、ある種の民間伝承です。Eq (これには引数の分析が必要です) とモノイドを組み合わせると、モノイドの新しいクラスが導入されます。そしてこの時点で、Eq-Monoid はその Monoid スーパークラスの精神に反するという合理的な議論があります (Monoid は不透明です)。これはオブジェクトの新しいクラスであり、論争の的となる可能性があるため、標準の実装は存在しません。

于 2012-11-29T18:36:20.237 に答える