我想了解这些例子,但他们在Scheme中。我希望他们在Clojure:D
示例1 - 计算列表的长度
(define length
(lambda (ll)
(cond
((null? ll) 0)
(#t (add1
(length (cdr ll)))))))
例2 - 对列表中的每个元素进行平方
(define squares
(lambda (li)
(cond
((null? li) ())
(#t (cons
(* (char li) (char li))
(squares(cdr
li)))))))
示例3 - “地图”功能(如map / reduce中所示)
(define map (lambda (func lst)
(cond ((null? lst) ())
(#t (cons (func (car lst))
(map func (cdr lst)))))))
咖喱“地图”
(define map2
(lambda (func)
(lambda (lst)
(cond ((null? lst) ())
(#t (cons (func (car lst))
((map2 func) (cdr lst)))))))
的动机
这些例子来自其他人可能感兴趣的功能编程演示文稿:Functional Languages 101: What’s All the Fuss About?
一旦您提交了答案,我希望您同意将其作为评论发布在Clojure人员的演示文稿中,以了解原始代码
答案 0 :(得分:6)
它的所有方案都是为了解决问题。您可以下载Essentials of Programming Languages-Book的源代码以获得Scheme代码。
以下是您的示例:
(defn length [lst]
(cond
(seq ll) 0
:else (inc (length (rest lst))))))
注意:clojure有一个计数功能
(defn squares1 [li]
(cond (nil? (seq li)) (empty li)
:else (conj (squares1 (rest li)) (* (first li) (first li)))))
(defn squares2 [li]
(map #(* % %) li))
(defn mymap [f coll]
(cond (nil? (seq coll)) (empty coll)
:else (conj (mymap f (rest coll)) (f (first coll)))))
(defn map2 [f]
(fn [lst]
(cond (nil? (seq lst)) (empty lst)
:else (conj ((map2 f) (rest lst)) (f (first lst))))))
请注意,您不能只进行1:1的翻译。 '()evals之间的差异等等。
以下是最重要的那些
答案 1 :(得分:5)
列表长度:
(defn my-length [lst]
(loop [len 0 x lst]
(if (empty? x)
len
(recur (+ 1 len) (rest x)))))
user=> (my-length '(1))
1
user=> (my-length '(1 2 3 4))
4
user=> (my-length '())
0
对列表中的每个元素进行平方:
(defn squares [lst]
(loop [sqrs '() x lst]
(if (empty? x)
(reverse sqrs)
(recur (cons (* (first x) (first x)) sqrs) (rest x)))))
user=> (squares '(1 2 3 4))
(1 4 9 16)
地图:
(defn my-map [func lst]
(loop [res '() x lst]
(if (empty? x)
(reverse res)
(recur (cons (func (first x)) res) (rest x)))))
user=> (my-map (fn [x] (* x 2)) '(1 2 3))
(2 4 6)
地图2:
请参阅nickik的解决方案。
答案 2 :(得分:2)
map
的更多clojurey翻译:
(defn map
[f coll]
(lazy-seq
(when-let [s (seq coll)]
(cons (f (first s)) (map f (rest s))))))
利用闭包:定义map-inner
,例如上面的map
。
(defn map
[f]
(fn [coll]
(map-inner f coll)))
在惯用语中,通常你会利用nil是逻辑错误的。
(defn length
[coll]
(loop [s (seq coll)
len 0]
(if s
(recur (next s) (inc len))
len)))
与map
一样:您将使用延迟序列而不是急切列表。
(defn squares
[coll]
(lazy-seq
(when-let [s (seq coll)]
(let [fst (first s)]
(cons (* fst fst) (squares (rest s)))))))
答案 3 :(得分:0)
define
在{* 1}}中是def
,lambda
是fn
,函数参数写为向量[]
,而不是列出()
,{ {1}}为null?
,empty
为car
,first
为cdr
,rest
的默认大小写为{{1} }},而不是cond
。
因此,对于您的第一个示例,我们得到:
:else
使用#t
而不是(def length
(fn [ll]
(cond
(empty? ll) 0
:else (+ 1 (length (rest ll))))))
和defn
可以更简洁地写出来,但对于方案版本也是如此,所以我选择了最接近的方式原来的。
其他例子可以用同样的方式翻译。