Haskell: Лучший способ написать Maybe Endo?

Я только что обнаружил тип Endo благодаря network-api-support package, и я обнаружил, что необходимо иметь возможность добавлять значения Maybe в Endo. В результате я написал функцию с именем mayEndo. Вот пример его использования:

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

Что меня поражает, так это то, что это похоже на то, что уже должно быть заключено в какой-то шаблон.


person Robert Massaioli    schedule 25.10.2014    source источник


Ответы (2)


Вы уже нашли maybe (Endo id). Но Endo — это экземпляр Monoid, а Endo id — его нейтральный элемент mempty. Таким образом, вы также можете написать более широко

maybeMonoid :: Monoid b => (a -> b) -> Maybe a -> b
maybeMonoid = maybe mempty

Это уже довольно идиоматично (много совпадений, когда вы гуглите "maybe mempty"). Вы можете быть еще более общим, используя функцию из Data.Foldable:

foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b

так что с этим вы можете написать

setPotentialProxy :: Maybe Proxy -> RequestTransformer
setPotentialProxy = foldMap setProxy

(но убедитесь, что вы оставили подпись типа, иначе вы потратите слишком много времени на ее выяснение позже, когда будете читать код :-)).

person Joachim Breitner    schedule 25.10.2014
comment
У него есть имя: foldMap! Отлично, это именно то, что я искал. Очень хороший ответ! - person Robert Massaioli; 26.10.2014

И когда я писал этот вопрос, мне пришло в голову решение:

maybeEndo :: (a -> Endo b) -> Maybe a -> Endo b
maybeEndo = maybe (Endo id)

Это означает, что setPotentialProxy может быть просто:

setPotentialProxy :: Maybe Proxy -> RequestTransformer
setPotentialProxy = maybe (Endo id) setProxy

Тем не менее, я все же решил опубликовать этот вопрос, потому что, возможно, есть еще более естественный способ справиться с этим сценарием. И, возможно, это поможет кому-то еще.

person Robert Massaioli    schedule 25.10.2014