Я пытался взять некоторые простые функции и преобразовать их в бессмысленный стиль для практики.
Я начал с чего-то вроде этого:
zipSorted x y = (zip . sort) y $ sort x --zipSorted(x, y) = zip(sort(y), sort(x))
и в конечном итоге преобразовал его в
zipSorted = flip (zip . sort) . sort
(я не уверен, что это даже лучший способ сделать это, но это работает)
Теперь я пытаюсь еще больше уменьшить это выражение, так как оно не зависит от zip
и sort
. Другими словами, я ищу эту функцию: (Я думаю, что это комбинатор, если мой словарь не ошибается)
P(f, g, x, y) = f(g(y), g(x))
Тот факт, что sort
присутствует дважды, но передается только один раз, намекал мне на то, что мне следует использовать оператор аппликативного функтора <*>
, но я не могу понять, как по какой-то причине.
Насколько я понимаю, (f <*> g)(x) = f(x, g(x))
, поэтому я попытался переписать первое бессмысленное выражение в этой форме:
flip (zip . sort) . sort
(.) (flip $ zip . sort) sort
(flip (.)) sort $ flip (zip . sort)
(flip (.)) sort $ flip $ (zip .) sort
Кажется, что sort
должно быть x
, (flip (.))
должно быть f
, а flip . (zip .)
должно быть g
.
p = (flip (.)) <*> (flip . (zip .))
p sort [2, 1, 3] [4, 1, 5]
дает [(1, 1), (4, 2), (5, 3)]
, как и ожидалось, но теперь я теряюсь в том, как вытащить zip
. Я пробовал
p = (flip (.)) <*> (flip . (.))
p zip sort [2, 1, 3] [4, 1, 5]
но это не работает. Есть ли способ преобразовать это выражение в комбинатор, который выделяет zip
?