What is the mempty datatype?
I have the following datatype with monoid and semigroup instance:
newtype Combine a b =
Combine { unCombine :: a -> b }
instance (Semigroup b)
=> Semigroup (Combine a b) where
Combine {unCombine=f} <> Combine {unCombine=g} = Combine (f <> g)
instance (Semigroup b, Monoid b)
=> Monoid (Combine a b) where
mempty = Combine mempty
mappend = (<>)
I want to customize it, what is the value mempty
for the function (->)
?
I tried for example:
*Exercises Data.Monoid> mempty :: (-> Integer Bool)
<interactive>:21:15: error: parse error on input `Integer'
What does the implementation look like mempty
in monoid
?
I looked at the source of the hack:
instance Monoid b => Monoid (a -> b) where
mempty _ = mempty
mappend f g x = f x `mappend` g x
and cannot find an implementation mempty
.
Perhaps to clarify what I mean, consider the following example:
*Exercises Data.Monoid> mempty :: (Product Integer)
Product {getProduct = 1}
The mempty element Product Integer
is Product {getProduct = 1}
.
source to share
- A type constructor is
(->)
not a type constant (no type values(->)
) and therefore cannot have a monoid instance. - If the type
b
has a monoid instance, the type constanta -> b
(or(->) a b
) has a monoid instance andmempty
gives a function that ignores its inputs and returnsmempty
ofb
as a value.
If you look
instance Monoid b => Monoid (a -> b) where
mempty _ = mempty
mappend f g x = f x `mappend` g x
the line implements this.mempty _ = mempty
What is the type mempty
for a -> b
? This a -> b
is because it mempty
must be a value of the type a -> b
. So
mempty _ = mempty
tells us what mempty
for a -> b
is a function that discards its input and returns , a value of type . The two occurrences of the name in this definition refer to different functions / values. mempty
b
mempty
Apply some specific examples:
-
You tried
mempty :: (-> Integer Bool)
which is syntactically incorrect. You wanted to try
mempty :: (->) Integer Bool
which gives a new error
<interactive>:5:1: error: β’ No instance for (Monoid Bool) arising from a use of βmemptyβ β’ In the expression: mempty :: (->) Integer Bool In an equation for βitβ: it = mempty :: (->) Integer Bool
since it
Bool
does not have a monoid instance. -
You tried
mempty :: (Product Integer)
which worked and gave
Product {getProduct = 1}
as meaning. This tells you itProduct Integer
has a monoid instance. Therefore, we could try to haveProduct Integer
both type in .b
a -> b
-
Now try
> let f = mempty :: a -> Product Integer > f 'x' Product {getProduct = 1}
In this example, it
mempty
refers to some value of the typea -> Product Integer
and is therefore a function. So the type variablet
frommempty :: (Monoid t) => t
in this case is of the typea -> Product Integer
.
source to share