6 haskell monoids maybe semigroup
Maybe
表示可能由于错误而不会产生结果的计算.因此,这种计算必须短路.
现在Maybe
的Semigroup/Monoid实例似乎打破了这种语义,因为前者偏向于Just
,后者将错误情况Nothing
视为空元素:
Just "foo" <> Nothing -- Just "foo"
Nothing <> Just "bar" -- Just "bar"
Just "foo" <> Just "bar" -- Just "foobar"
Nothing <> Nothing -- Nothing
Run Code Online (Sandbox Code Playgroud)
我期望Nothing
前两个案例.
这是替代实现(希望它是正确/合法的):
instance Semigroup a => Semigroup (Maybe a) where
Nothing <> _ = Nothing
_ <> Nothing = Nothing
Just a <> Just b = Just (a <> b)
instance Monoid a => Monoid (Maybe a) where
mempty = Just mempty
Run Code Online (Sandbox Code Playgroud)
我不想说这些替代实例更好.但它们似乎也很有用.那么为什么首先进行选择而不是将实现留给用户呢?
您的实例实际上是应用函子的更通用实例的特例.
newtype LiftA f a = LiftA { getLiftA :: f a }
instance (Applicative f, Semigroup a) => Semigroup (LiftA f a) where
LiftA x <> LiftA y = LiftA $ liftA2 (<>) x y
instance (Applicative f, Monoid a) => Monoid (LiftA f a) where
mempty = LiftA $ pure mempty
Run Code Online (Sandbox Code Playgroud)
我认为它会在某个地方的标准库中(可能在不同的名称下),但我找不到它.但这种一般情况的存在可能是选择图书馆版本的一个原因Maybe
,这更具有Maybe
特殊的权力.另一方面,当你的代数结构彼此连贯时,它是相当不错的; 即,当类型为a 时,尽可能Applicative
使用" LiftA
"样式实例(在所有F代数类上).
在第三手(!),我们不能有连贯性无处不在,因为库实例与同意Maybe
的MonadPlus
情况下.这与自然数上存在两个幺半群的事实惊人地相似:加法和乘法.对于数字,我们选择不要有任何 monoid实例,因为它不清楚使用哪个.
总之,我不知道.但也许这些信息很有帮助.