[英]Derive monoid instance for custom `Maybe` data type
For learning purposes, i am trying to create an Optional
data type that mimics Maybe
in the typeclass instance of Monoid
where 出于学习目的,我试图在
Monoid
的typeclass实例中创建一个模拟Maybe
的Optional
数据类型,其中
-- Data.Monoid> Prelude.mappend (Just [1,2]) (Just [3,4])
-- Just [1,2,3,4]
Instead, I am getting the behavior of the First
instance of Maybe
for Monoid
. 相反,我得到了
Maybe
for Monoid
的First
实例的行为。
-- Data.Monoid> (First (Just [1,2])) <> (First (Just [3,4]))
-- First {getFirst = Just [1,2]}
My data type and typeclass instance are: 我的数据类型和typeclass实例是:
data Optional a =
Nada
| Only a
deriving (Eq, Show)
instance Monoid a
=> Monoid (Optional a) where
mempty = Nada
mappend x mempty = x
mappend mempty (Only x) = Only x
mappend (Only x) (Only y) = Only (Prelude.mappend x y)
My questions are 我的问题是
mappend
for Optional
to behave like the instance for Maybe
that concatenates lists rather than taking the first Only
value? mappend
用于Optional
的行为像实例Maybe
是符连接列表而不是将第一Only
值? Why does it behave like this?
为什么会这样呢?
Because that is how First
has been designed. 因为这就是
First
设计方式。 The idea of First
is to "wrap" a Maybe a
value, and to implement the Monoid
like: First
的想法是“包装”一个Maybe a
值,并像下面这样实现Monoid
:
instance Monoid (First a) where
mempty = First Nothing
mappend l@(First (Just _)) _ = l
mappend _ x = x
It thus returns the first First
constructor that wrapps a value Just
data constructor. 因此,它返回包装了值
Just
数据构造函数的第一个First
构造函数。 This can be useful when we use the mconcat
: 当我们使用
mconcat
时,这可能会很有用:
Prelude Data.Monoid> mconcat [First Nothing, First (Just 0), First Nothing, First (Just 118), First (Just 999)]
First {getFirst = Just 0}
We thus do not use the Monoid (Maybe a)
implementation, the First
decides how the Monoid
looks like. 因此,我们不使用
Monoid (Maybe a)
实现,由First
决定Monoid
外观。 A similar thing happens with Sum
and Product
Sum
和Product
Sum
发生类似的情况
How do I get
mappend
forOptional
to behave like the instance forMaybe
that concatenates lists rather than taking the firstOnly
value?如何获得
mappend
用于Optional
的行为像实例Maybe
是符连接列表而不是将第一Only
值?
There is an error in your definition. 您的定义中有错误 。 You use
mempty
in the head of a function like: 您可以在以下函数的开头使用
mempty
:
mappend x
mempty = x
is just a variable named mempty
. 只是一个名为
mempty
的变量 。 So the first line will match everything . 因此,第一行将匹配所有内容 。 You should fix it, like you intend with:
您应该修复它,就像您打算使用的那样:
instance Monoid a => Monoid (Optional a) where
mempty = Nada
mappend x
Nada = x
mappend
Nada x = x
mappend (Only x) (Only y) = Only (Prelude.mappend x y)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.