在Clojure中,是否有类似Haskell的函数?

yur*_*riq 11 haskell functional-programming clojure combinators

在Haskell,我们有Data.Function.on:

on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
(.*.) `on` f = \x y -> f x .*. f y
Run Code Online (Sandbox Code Playgroud)

在Clojure中,我希望能够定义一个例如anagram谓词,如下所示:

(defn anagram? [word other-word]
  (and (not= word other-word)
       ((on = sort) word other-word)))
Run Code Online (Sandbox Code Playgroud)

实施起来很简单:

(defn on [g f] (fn [x y] (g (f x) (f y))))
Run Code Online (Sandbox Code Playgroud)

但是,是否有任何内置函数可以实现相同的目标?我好像找不到一个.

ama*_*loy 4

不,没有内置功能可以满足您的需求。不过,如果你打算实现它,我认为你可以做得更通用一些,因为 Clojure 有 vararg 支持并且缺乏柯里化:

(defn on
  ([f g]
     (fn [x y]
       (f (g x)
          (g y))))
  ([f g & args]
     (on f #(apply g % args))))
Run Code Online (Sandbox Code Playgroud)

这可以让你写一些类似的东西

(defn same-parity? [x y]
  ((on = mod 2) x y))
Run Code Online (Sandbox Code Playgroud)

当然,这在 Haskell 中也很容易,因为

sameParity :: (Integral a) => a -> a -> Bool
sameParity = (==) `on` (`mod` 2)
Run Code Online (Sandbox Code Playgroud)

但在 Clojure 中,mod 的部分应用有点棘手,因此如果可以的话,通常会通过 &args 提供等效的功能。