haskellmaxmonoidsbounded-typesfoldable# How to compute the maximum of a floating point property of a Foldable via foldMap?

Say I have a map with measurable objects, and I'd like the maximum of their widths, defaulting to 0. The machinery of `Foldable`

(`foldMap`

) and `Semigroup`

(`Max`

) seems perfect, except that I can't seem to introduce the arbitrary lower bound.

```
data Thing
width :: Thing -> Double
maxWidth :: Map k Thing -> Double
maxWidth things = getMax . foldMap (Max . width) $ things
```

This rightly complains about the missing `Bounded`

instance for `Double`

, since the `Monoid`

instance of `Max a`

uses `mempty = minBound`

.

I see that the source for `Data.Foldable`

uses a different definition of `newtype Max`

to implement `maximum`

. That variant would do nicely, but it seems to not be exported:

```
maxWidth things = fromMaybe 0 . getMax . foldMap (Max . Just . width) $ things
```

Solution

You can use the ** Option** monoid to get a monoid instance for any

`Semigroup`

. `Option a`

is just a newtype wrapper over `Maybe a`

, but it's `Monoid`

instance only requires `Semigroup a`

rather than `Monoid a`

. So we can use it with `Max`

: ```
maximumMaybe :: (Ord a, Foldable t) => t a -> Maybe a
maximumMaybe = fmap getMax . getOption . foldMap (Option . Just . Max)
```

If you want a default value for the empty list case, you can use `fromMaybe`

:

```
maximumWithDefault :: (Ord a, Foldable t) => a -> t a -> a
maximumWithDefault d = fromMaybe d . maximumMaybe
```

Another option is to just use ** maximumMay :: (Ord a, Foldable t) => t a -> Maybe a** from the

`safe`

package.If you are using `base-4.11.0`

or higher, you no longer need the `Option a`

type since the restriction on `Monoid (Maybe a)`

has been lifted to `Semigroup a`

. So as of `base-4.11.0`

, which came with GHC 8.4.1, you can write:

```
maximumMaybe :: (Ord a, Foldable t) => t a -> Maybe a
maximumMaybe = fmap getMax . foldMap (Just . Max)
```

- What is the proper way of wrapping an Int (not a general type) in another type if type safety is the only motive?
- What is the most practical way to express a dependency on a library for which we have a local git repository with some changes?
- Htmx POST to haskell servant handling optional field in FormUrlEncoded request
- Haskell fails to infer the return type of a monad after using the sequence operator
- Does extracting values from a multiple Value return in Haskell invoke the function more than once?
- How to specify c/c++ compiler on stack install command
- Why do I get "Unexpected reply type" from notify-send when using this Haskell notification server?
- Don't understand notation of morphisms in Monoid definition
- Foldln in haskell
- Is this property of a functor stronger than a monad?
- How to Instantiate a Custom Data Type with Record Syntax and Multiple Constructors
- How do I make a minimal working example for the a DBus server?
- Is it safe to downgrade Haskell stack version?
- Haskell, list of natural number
- unfamiliar syntax in Haskell / Clash function type signature
- foldM with monad State does not type check
- Why does my Runge-Kutta implementation oscillate to 0?
- How do I get the desired behavior in my TCP server?
- Why does the Haskell PVP describe new functions as non-breaking?
- How do I correctly use toLower in Haskell?
- How can I write a notification server in Haskell?
- Every Lens' is a Traversal'... how?
- How do I crate a value of type a{sv} for a call to org.freedesktop.Notifications.Notify via DBus?
- Web Scraping With Haskell
- Double exclamation marks in Haskell
- Haskell Servant POST FormUrlEncoded for (Vector String) field
- Confusion about list types in Haskell
- Idiomatic way to define new vs persisted types in Haskell
- Why does Cabal, unlike GHC, not automatically enable GeneralizedNewtypeDeriving if I explicitly enabled DerivingStrategies?
- Parsing inside `between` with Megaparsec