I tried to write a generalized maximum
function similar to the one in Prelude
. My first naiv approach looked like this:maximum' :: (F.Foldable a, Ord b) => a b -> Maybe b
maximum' mempty = Nothing
maximum' xs = Just $ F.foldl1 max xs
However, when I test it it always returns Nothing
regardless of the input:> maximum' [1,2,3]
> Nothing
Now I wonder whether it's possible to obtain the empty value of a Monoid type instance. A test function I wrote works correctly:getMempty :: (Monoid a) => a -> a
getMempty _ = mempty
> getMempty [1,2,3]
> []
I had already a look at these two questions but I didn't figure out how the answers solve my problem:
Write a Maximum Monoid using Maybe in Haskell
Haskell Pattern Matching on the Empty Set
How would I rewrite the maximum'
function to get it to work ?
As C. A. McCann points out in his comment, you can't pattern match on values, only patterns.
The equation maximum' mempty = Nothing
is actually equivalent to the equation maximum' x = Nothing
. The argument gets bound to a name and Nothing
is returned.
Here's a way to make your code work:
maximum' :: (F.Foldable a, Ord b, Eq (a b), Monoid (a b)) => a b -> Maybe b
maximum' xs
| xs == mempty = Nothing
| otherwise = Just $ F.foldl1 max xs
I.e. you can compare the value xs
against mempty
. Note that we need a Monoid
constraint to be able to get at the value mempty :: a b
and an Eq
constraint to be able to compare as well.
An other, more elegant, solution would be to use a fold to differentiate between the empty and non-empty cases:
maximum'' :: (F.Foldable a, Ord b) => a b -> Maybe b
maximum'' xs = F.foldl max' Nothing xs
where max' Nothing x = Just x
max' (Just y) x = Just $ max x y
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With