在Clojure中,有没有像Haskell这样的函数?
In Clojure, is there a function like Haskell's on?
在 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))))
但是有没有内置函数
实现相同的目标?
我好像找不到。
不,没有内置功能可以满足您的需求。不过,如果您要实现它,我认为您可以负担得起更通用的代码,因为 Clojure 支持可变参数并且缺少柯里化:
(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 中 mod 的部分应用有点棘手,所以如果可以的话,习惯上通过 &args 提供等效的功能。
在 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))))
但是有没有内置函数 实现相同的目标? 我好像找不到。
不,没有内置功能可以满足您的需求。不过,如果您要实现它,我认为您可以负担得起更通用的代码,因为 Clojure 支持可变参数并且缺少柯里化:
(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 中 mod 的部分应用有点棘手,所以如果可以的话,习惯上通过 &args 提供等效的功能。