Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: Better way of writing Maybe Endo?

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.

like image 226
Robert Massaioli Avatar asked Oct 25 '14 09:10

Robert Massaioli


Video Answer


1 Answers

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 :-)).

like image 53
Joachim Breitner Avatar answered Sep 20 '22 15:09

Joachim Breitner