你能从函数式语言101中翻译这两个例子吗?(方案->;Clojure)

你能从函数式语言101中翻译这两个例子吗?(方案->;Clojure),clojure,scheme,Clojure,Scheme,我想了解这些例子,但它们都在计划中。我想要Clojure:D的 示例1计算列表的长度 (define length (lambda (ll) (cond ((null? ll) 0) (#t (add1 (length (cdr ll))))))) (define squares (lambda (li) (cond ((null? li) ()) (#t (cons (* (c

我想了解这些例子,但它们都在计划中。我想要Clojure:D的

示例1计算列表的长度


(define length
  (lambda (ll)
    (cond
      ((null? ll) 0)
      (#t (add1
        (length (cdr ll)))))))

(define squares
  (lambda (li)
    (cond
      ((null? li) ())
      (#t (cons
            (* (char li) (char li))
            (squares(cdr
    li)))))))
示例2-将列表中的每个元素平方


(define length
  (lambda (ll)
    (cond
      ((null? ll) 0)
      (#t (add1
        (length (cdr ll)))))))

(define squares
  (lambda (li)
    (cond
      ((null? li) ())
      (#t (cons
            (* (char li) (char li))
            (squares(cdr
    li)))))))
示例3“地图”功能(如地图/缩小)

咖喱“地图”

动机 示例来自函数式编程的演示,其他人可能对此感兴趣:


一旦您提交了答案,我希望您同意将其作为评论发布在该演示文稿上,以便Clojure人理解原始代码

define
在Clojure中是
def
lambda
fn
,函数参数是作为向量编写的
[
,而不是列表
()
null?
empty
car
first
cdr
rest
cond
的默认大小写指定为
:else
,而不是
\t

因此,对于您的第一个示例,我们得到:

(def length
  (fn [ll]
    (cond
      (empty? ll) 0
      :else (+ 1 (length (rest ll))))))
这可以使用
defn
而不是
def
fn
更简洁地编写,但scheme版本也是如此,因此我选择了最接近原始版本的方式

其他示例可以用同样的方式翻译。

列表长度:

(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-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)
地图:

地图2:

参见nickik的解决方案

我这里有一些干草:

这一切都是为了掩盖事实。您可以下载《编程语言精要》一书的源代码来获得方案代码


以下是您的示例:

(defn length [lst]
    (cond
      (seq ll) 0
      :else (inc (length (rest lst))))))
注意:clojure有一个计数函数




请注意,您不能仅进行1:1的翻译。“如何”(how)求值等之间的差异

这里是最重要的

  • (nil?(seq list))not(null?lst),因为“()在clojure中不是nil
  • conj比cons更好,您可以使函数与mure数据结构一起工作
  • (empty lst)比“()更好,因为(empty lst)保留类型向量、列表、记录、结构或其他内容

    • 以及更多的
      地图的clojurey翻译:

      (defn map
        [f coll]
        (lazy-seq
          (when-let [s (seq coll)]
            (cons (f (first s)) (map f (rest s))))))
      
      利用闭包:像上面的
      map
      一样定义
      map内部

      (defn map
        [f]
        (fn [coll]
          (map-inner f coll)))
      
      在惯用的clojure中,通常可以利用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)))))))
      

      @贝伦:那只是一个名字
      lambda(func-lst)
      是一个包含两个参数的lambda,分别名为
      func
      lst
      。clojure的等价物是
      fn[func lst]
      @sepp2k>这里有一个挑战:您能否创建并使用宏,例如1和2P@nickik:方案版本也不是。正如我所说,我给出了最类似于原始版本的版本。@sepp2k>是的,1个宏获取一些参数,然后可以构建这2个函数
      (defn length
        [coll]
        (loop [s   (seq coll)
               len 0]
          (if s
            (recur (next s) (inc len))
            len)))
      
      (defn squares
        [coll]
        (lazy-seq
          (when-let [s (seq coll)]
            (let [fst (first s)]
              (cons (* fst fst) (squares (rest s)))))))