(+)
とは;(++)
の単なる特殊化です。mappend
私は正しいですか?なぜ必要なのですか?Haskell にはこれらの強力な型クラスと型推論があるため、これは無駄な重複です。視覚的な利便性とタイピングの向上のために、削除(+)
し(++)
て名前を変更するとしましょう。mappend
(+)
コーディングは、初心者にとってより直感的で、短く、理解しやすいものになります。
--old and new
1 + 2
--result
3
--old
"Hello" ++ " " ++ "World"
--new
"Hello" + " " + "World"
--result
"Hello World"
--old
Just [1, 2, 3] `mappend` Just [4..6]
--new
Just [1, 2, 3] + Just [4..6]
--result
Just [1, 2, 3, 4, 5, 6]
(それは私に夢を与えます。)Haskell のような抽象化を主張する美しい言語にとって、3 つ、あるいはそれ以上の関数が同じことを行うのは良いことではありません。モナドでもfmap
同じ種類の繰り返しを見た. Haskell 委員会はこれについて何か計画を立てていますか? それはいくつかのコードを壊すだろうが、確かではないが、大きな変更を加えた次のバージョンがあると聞いた.これは素晴らしい機会だ. 残念すぎる… せめてフォークくらいは買えるの?map
(.)
liftM
mapM
forM
fmap
編集(*)
私が読んだ回答では、数字の場合、または(+)
に収まる可能性が
あるという事実がありますmappend
。実際、それは!(*)
の一部であるべきだと思います。Monoid
見て:
現在、関数mempty
と を忘れて、mconcat
しかありませんmappend
。
class Monoid m where
mappend :: m -> m -> m
しかし、私たちはそれを行うことができます:
class Monoid m where
mappend :: m -> m -> m
mmultiply :: m -> m -> m
次のように動作します (おそらく、まだ十分に理解していません)。
3 * 3
mempty + 3 + 3 + 3
0 + 3 + 3 + 3
9
Just 3 * Just 4
Just (3 * 4)
Just (3 + 3 + 3 +3)
Just 12
[1, 2, 3] * [10, 20, 30]
[1 * 10, 2 * 10, 3 * 10, ...]
[10, 20, 30, 20, 40, 60, ...]
実際には、'mmultiply' は 'mappend' に関してのみ定義されるため、インスタンスのMonoid
場合は再定義する必要はありません! 次にMonoid
、数学に近づきます。クラスに(-)
andを追加することもできます。これが機能する場合、関数の重複と同様に and のケースも解決すると思います:に(/)
なり、new is just . 基本的に、「プルアップ」を使用してコードをリファクタリングすることをお勧めします。ああ、新しいforも必要です。これらの演算子をクラスで抽象化し、次のように定義できます。Sum
Product
mappend
(+)
mmultiply
(*)
mempty
(*)
MonoidOperator
Monoid
class (Monoid m) => MonoidOperator mo m where
mempty :: m
mappend :: m -> m -> m
instance MonoidOperator (+) m where
mempty = 0
mappend = --definition of (+)
instance MonoidOperator (*) where
--...
class Monoid m where
-...
これを行う方法はまだわかりませんが、これらすべてに対するクールな解決策があると思います。