I have just discovered the Endo type thanks to the network-api-support package and I have found the need to be able to throw Maybe values into Endo's. As a result I have written a function called maybeEndo. Here is an example of it being used:
setProxy :: Proxy -> RequestTransformer
setProxy (Proxy pHost pPort) = Endo $ addProxy pHost pPort
maybeEndo :: (a -> Endo b) -> Maybe a -> Endo b
maybeEndo _ Nothing = Endo id
maybeEndo f (Just v) = f v
setPotentialProxy :: Maybe Proxy -> RequestTransformer
setPotentialProxy = maybeEndo setProxy
What strikes me is that this seems like something that should be encapsulated into some type of pattern already.
You already found maybe (Endo id)
. But Endo
is an instance of Monoid
, and Endo id
is its neutral element mempty
. So you could also write more generally
maybeMonoid :: Monoid b => (a -> b) -> Maybe a -> b
maybeMonoid = maybe mempty
This is already quite idiomatic (plenty of hits when you google for "maybe mempty"
). You can be even more general by using a function from Data.Foldable
:
foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
so with this, you can write
setPotentialProxy :: Maybe Proxy -> RequestTransformer
setPotentialProxy = foldMap setProxy
(but make sure you leave in the type signature, otherwise you’ll spend too much time figuring it out later when you read the code :-)).
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