Understanding `mempty`

Any is one of the 2 possible monoid instances for Bool (the other being All).

mempty is required to have the following property

mempty <> a = a
a <> mempty = a
In words: no matter what other element you combine mempty with, the result has to be the other element. We call mempty identity element, because combining mempty with some other element behaves like the identity function.

If you look at Bool’s && operation, you might notice that
True && True = True
True && False = False
False && True = False
False && False = False
so in this case it’s True that satisfies the property of being identity element for the && operation.

The similar pattern occurs for ||:
False || False = False
False || True = True
True || False = True
True || True = True
In this case False is the identity element of the || operation.

Now (after checking that both operations are associative of course) you see there are at least 2 valid monoid instances for Bool (one using || as mappend, the other using && as mappend). But in Haskell any given type can have at most one instance for any given type class. This restriction is usually worked around by using a newtype.
By wrapping Bool in Any / All respectively you effectively create 2 distinct types and you can provide distinct monoid instance for each of them.

newtype Any = Any { getAny :: Bool }
newtype All = All { getAll :: Bool }

instance Monoid Any where
    mempty = Any False
    mappend (Any a) (Any b) = Any (a || b)

instance Monoid All where
    mempty = All True
    mappend (All a) (All b) = All (a && b)

(In base the instances look a bit different due to Semigroup being superclass of Monoid, but they are equivalent to the above)

So why is mempty : Any equal to Any False?

This hopefully explains why mepmty :: Any gives you Any False. I hope you see the pattern based on the above:
Any False <> Any False = Any False
Any False <> Any True = True
Any True <> Any False = Any True
Any True <> Any True = Any True
Because it acts as identity element with respect to the <> operation.

Back to your examples:
why is (mempty :: whatever -> Any) whaveteveValue always returning Any False?
That’s because how Monoid (a -> b) is defined. mepmty of type a -> b is a function which takes a and returns mempty of type b. And since mempty :: Any is Any False you see that behavior :grinning_face_with_smiling_eyes:

Now why would you ever use Any / All if you can use || and && directly?
There are many useful operations (e.g. look at foldMap) that ask you to provide an instance of Monoid (as opposed to concrete type like bool) and in such cases Any / All become handy.

2 Likes

That was very interesting! I now understand the answer to the question and a couple of other things.

> (mempty :: String -> All) "abc"
All {getAll = True}

> (mempty :: String -> Any) "abc"
Any {getAny = False}

@jhrcek - was response to your last post. Isn’t showing that to me so mentioning.