Подтвердить что ты не робот

В Clojure существует ли функция, такая как Haskell?

В Haskell мы Data.Function.on:

on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
(.*.) `on` f = \x y -> f x .*. f y

В Clojure, я хочу иметь возможность определить, например, предикат анаграммы следующим образом:

(defn anagram? [word other-word]
  (and (not= word other-word)
       ((on = sort) word other-word)))

Это тривиально реализовать:

(defn on [g f] (fn [x y] (g (f x) (f y))))

Но есть ли встроенная функция что достигает той же цели? Кажется, я не могу найти его.

4b9b3361

Ответ 1

Нет, нет встроенного, который делает то, что вы ищете. Однако, если вы собираетесь его реализовать, я думаю, что вы можете позволить себе быть более родовым, поскольку Clojure имеет поддержку vararg и не имеет currying:

(defn on
  ([f g]
     (fn [x y]
       (f (g x)
          (g y))))
  ([f g & args]
     (on f #(apply g % args))))

Это позволяет вам написать что-то вроде

(defn same-parity? [x y]
  ((on = mod 2) x y))

что, конечно же, легко и в Haskell, так как

sameParity :: (Integral a) => a -> a -> Bool
sameParity = (==) `on` (`mod` 2)

Но в Clojure частичное применение мода немного сложнее, поэтому обычно можно предоставлять эквивалентную функциональность через & args, если вы можете.