Как построить "недостающие" сложные функции в Haskell

Как я должен подойти к ситуациям, когда я знаю тип необходимой функции, но она еще не определена? Я подозреваю, что функцию, которую я ищу, легко составить из других, но я не знаю, с чего начать.

Prelude> :hoogle (b->b->c)->(a->b)->(a->b)->a->a->c
No results found

Чтобы быть более конкретным, у меня есть (b->b->c) функция под рукой, но мне нужно сначала обработать (поднять, может быть?) аргументы. Может ли Google найти функции с аргументами в другом порядке, чем указано?

Это близко к тому, что мне нужно, но я хочу применить разные функции к каждому аргументу.

Prelude Data.Function> :t on
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c

2 ответа

Решение

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

import Control.Arrow
on2 :: (b -> b -> c) -> (a -> b) -> (a -> b) -> a -> a -> c
on2 f g h = curry (uncurry f . (g *** h))

Тем не менее, простое определение, предложенное bheklilr, очевидно, столь же лаконично и гораздо более читабельно для людей, которые не привыкли работать со стрелками.

И да, насколько я знаю, Hoogle также выполняет поиск функций, в которых указан порядок типов аргументов, который вы указали.

Если вы не нашли его в Google, вероятно, он еще не определен. Не стесняйтесь определять свой собственный как

on2 :: (b1 -> b2 -> c) -> (a1 -> b1) -> (a2 -> b2) -> a1 -> a2 -> c
on2 f p1 p2 a1 a2 = f (p1 a1) (p2 a2)

Но это привело бы к таким выражениям, как

on2 zip init tail xs ys

Вместо просто

zip (init xs) (tail ys)

Так что я не знаю, если это действительно сэкономит вам много места.

Другие вопросы по тегам