Общий шаблон, включающий композицию функций (\a b -> f (g a) (g b))

Композиция f и g, которая выглядит как

f :. g = \a b -> f (g a) (g b)

это шаблон, который я очень часто встречаю в своем коде. Это похоже на композицию унарной функции, только f является двоичной, и я хочу, чтобы g применялось к обоим аргументам до того, как они будут переданы в f.

Когда я прошу лямбдабота преобразовать это в бесточечную форму, я получаю странное заклинание

flip ((.) . f . g) g

чего я бы предпочел не иметь в своем коде, поэтому я просто явно пишу шаблон.

Есть ли общепринятый способ написания комбинатора для этой ситуации? Или я странный, потому что часто оказываюсь в этой ситуации?

У меня нет фактического примера того, когда я использую это прямо сейчас, так как я никогда не думал спрашивать здесь, когда мне это нужно, но можно было бы очень аккуратно написать с ним формулу евклидова расстояния, например так:

distance = sqrt . (+) :. (^2)

person kqr    schedule 28.09.2013    source источник
comment
flip можно исключить: (. g) . f . g   -  person Sassa NF    schedule 28.09.2013


Ответы (1)


Эта функция называется on в модуле Data.Function.

Часто используется инфикс, например sqrt . (+) `on` (^2).

person Roman Cheplyaka    schedule 28.09.2013
comment
Не могу поверить, что я не подумал об этом! Огромное спасибо. - person kqr; 28.09.2013
comment
Распространенный пример использования: sortBy (compare `on` abs) - person J. Abrahamson; 13.10.2013
comment
Однако я отмечу для будущих пользователей Google, что comparing abs более идиоматичен, чем compare `on` abs. Это работает, потому что comparing = on compare определен где-то в стандартных библиотеках. - person kqr; 23.12.2014