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

发布于 2024-09-27 10:35:53 字数 1159 浏览 3 评论 0原文

得到了这些例子,我想理解,但它们在方案中。我希望它们在 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”函数(如map/reduce)


(define map (lambda (func lst)
  (cond ((null? lst) ())
        (#t (cons (func (car lst))
              (map func (cdr lst)))))))

柯里化“map”


(define map2
  (lambda (func)
    (lambda (lst)
      (cond ((null? lst) ())
        (#t (cons (func (car lst))
              ((map2 func) (cdr lst)))))))

动机

这些示例来自有关函数式编程的演示文稿,其他人可能对此感兴趣:函数式语言 101:什么有什么大惊小怪的吗?

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

Got these examples I would like to understand but they are in Scheme. I would like them in Clojure :D

Example 1 - counting the length of a list


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

Exemple 2 - square each element of a list


(define squares
  (lambda (li)
    (cond
      ((null? li) ())
      (#t (cons
            (* (char li) (char li))
            (squares(cdr
    li)))))))

Example 3 - the "map" function (as in map/reduce)


(define map (lambda (func lst)
  (cond ((null? lst) ())
        (#t (cons (func (car lst))
              (map func (cdr lst)))))))

Curried "map"


(define map2
  (lambda (func)
    (lambda (lst)
      (cond ((null? lst) ())
        (#t (cons (func (car lst))
              ((map2 func) (cdr lst)))))))

Motivation

The examples are from a presentation on Functional Programming someone else might be interested it: Functional Languages 101: What’s All the Fuss About?

Once you submit an answer, I'd like your agreement to post it as a comment at that presentation for Clojure people to understand the original code

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陌上芳菲 2024-10-04 10:35:53

我这里有一些东西: http ://github.com/nickik/Essentials-of-PLs-in-Clojure/blob/master/src/EssentialsOfProgrammingLanguages/core.clj

这是 clojure 内容的所有方案。您可以下载Essentials ofProgramming 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 翻译。 '() 评估方式等之间的差异。

这里是最重要的

  • (nil? (seq list)) 不是 (null? lst) 因为 '() 在 clojure conj 中不是 nil
  • 比 conj 更好 缺点 你可以让函数使用更多数据结构
  • (空 lst) 更好'() 因为 (empty lst) 保留类型向量、列表、记录、结构或其他类型

I have some stoff here: http://github.com/nickik/Essentials-of-PLs-in-Clojure/blob/master/src/EssentialsOfProgrammingLanguages/core.clj

Its all scheme to clojure stuff. You can download the source of the Essentials of Programming Languages-Book to have the Scheme code.


Here are your examples:

(defn length [lst]
    (cond
      (seq ll) 0
      :else (inc (length (rest lst))))))

Note: clojure has a count function


(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))))))

Note you can not just make a 1:1 translation. The diffrence between how '() evals and so on.

Here are the most importend ones

  • (nil? (seq list)) not (null? lst) because '() is not nil in clojure
  • conj is better then cons you can make the function work with mure datastructures
  • (empty lst) is better then '() because (empty lst) keeps the type vector, list, record, structs or something else
墨洒年华 2024-10-04 10:35:53

列表的长度:

(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)

Map:

(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)

Map2:

参见 nickik 的解决方案。

Length of a list:

(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

Square each element of a list:

(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)

Map:

(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)

Map2:

See nickik's solution.

玩物 2024-10-04 10:35:53

还有 map 的更多 clojurey 翻译:

(defn map
  [f coll]
  (lazy-seq
    (when-let [s (seq coll)]
      (cons (f (first s)) (map f (rest s))))))

利用闭包:像上面的 map 一样定义 map-inner

(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)))))))

And more clojurey translation of map:

(defn map
  [f coll]
  (lazy-seq
    (when-let [s (seq coll)]
      (cons (f (first s)) (map f (rest s))))))

Exploit closures: define map-inner like map above.

(defn map
  [f]
  (fn [coll]
    (map-inner f coll)))

In idiomatic clojure normally you exploit that the nil is logical false.

(defn length
  [coll]
  (loop [s   (seq coll)
         len 0]
    (if s
      (recur (next s) (inc len))
      len)))

As with map: you would use lazy sequences instead of eager lists.

(defn squares
  [coll]
  (lazy-seq
    (when-let [s (seq coll)]
      (let [fst (first s)]
        (cons (* fst fst) (squares (rest s)))))))
乱了心跳 2024-10-04 10:35:53

define 在 clojure 中是 deflambdafn,函数参数写成向量 []< /code>,不列出 ()null?emptycarfirst,cdrrestcond 的默认情况是用 :else 指定的,而不是 #t

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

(def length
  (fn [ll]
    (cond
      (empty? ll) 0
      :else (+ 1 (length (rest ll))))))

使用 defn 而不是 deffn 可以更简洁地编写,但情况也是如此对于scheme版本,所以我选择了最接近原来的方式。

其他例子也可以用同样的方法翻译。

define is def in clojure, lambda is fn, function arguments are written as vectors [], not lists (), null? is empty, car is first, cdr is rest and the default case for cond is specified with :else, not #t.

So for your first example we get:

(def length
  (fn [ll]
    (cond
      (empty? ll) 0
      :else (+ 1 (length (rest ll))))))

This can be written a little more succinctly using defn instead of def and fn, but the same is true for the scheme version, so I chose the way that is the closest to the original.

The other examples can be translated the same way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文