(+)
并且(++)
只是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 之类的东西的美丽语言来说,为同一事物提供三个甚至更多的函数并不是一件好事。我还看到了与monad相同的重复:与, , , , ,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
更接近数学;也许我们也可以在课堂上添加(-)
和(/)
!如果这行得通,我认为它将解决Sum
andProduct
以及函数重复的情况:mappend
变得(+)
和新mmultiply
的只是(*)
. 基本上我建议用“上拉”重构代码。哦,我们还需要一个新mempty
的 for (*)
。我们可以将这些运算符抽象到一个类中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
-...
好吧,我还不知道该怎么做,但我认为所有这些都有一个很酷的解决方案。