Skip to content

Instantly share code, notes, and snippets.

@paomian
Last active June 22, 2021 02:51
Show Gist options
  • Save paomian/1f30bcda891ab9679001847f9bc367f6 to your computer and use it in GitHub Desktop.
Save paomian/1f30bcda891ab9679001847f9bc367f6 to your computer and use it in GitHub Desktop.
stream
;;不得不说,这思想很牛,但是理解起来也很绕,不知道这种代码到底是好还是不好。。。
;;想想不用这种方法怎么来实现这个功能,应该是用一个额外的表记录下所有前面的素数,然后用 (map (fn [x] (some (fn [y] (not-zero?(mod x y))) [primes list])) strems)
(defmacro my-delay [body]
`(fn [] ~body))
(defn my-force [f]
(f))
(def the-empty-stream [])
(def stream-null? empty?)
(defmacro cons-stream [x y]
`[~x (my-delay ~y)])
(defn stream-car [x]
(first x))
(defn stream-cdr [x]
(my-force (second x)))
(defn stream-ref [s n]
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (dec n))))
#_(defn stream-map [f s]
(println "hhh" s)
(if (empty? s)
the-empty-stream
(cons-stream (f (stream-car s))
(stream-map f (stream-cdr s)))))
(defn stream-map [f & s]
(if (empty? (first s))
the-empty-stream
(cons-stream
(apply f (map stream-car s))
(apply stream-map f
(map stream-cdr s)))))
(defn stream-for-each [f s]
(if (stream-null? s)
'done
(do (f (stream-car s))
(stream-for-each f (stream-cdr s)))))
(defn display-line [x]
(println x))
(defn display-stream [s]
(stream-for-each display-line s))
(defn stream-enumerate-interval [low high]
(if (> low high)
the-empty-stream
(cons-stream low (stream-enumerate-interval (inc low) high))))
(defn stream-filter [pred stream]
(cond (stream-null? stream) the-empty-stream
(pred (stream-car stream)) (cons-stream (stream-car stream)
(stream-filter pred (stream-cdr stream)))
:else (stream-filter pred (stream-cdr stream))))
(defn memo-proc [proc]
(let [already-run? (volatile! false)
result (volatile! false)]
(fn []
(if (not @already-run?)
(do (vreset! result (proc))
(vreset! already-run? true)
@result)
result))))
(defn integers-starting-from [n]
(cons-stream n (integers-starting-from (inc n))))
(def integers (integers-starting-from 1))
(def no-sevens (stream-filter (fn [x] (not= 0 (mod x 7)))
integers))
(defn divisible? [n m]
(zero? (mod n m)))
(defn sieve [stream]
(cons-stream
(stream-car stream)
(sieve (stream-filter
(fn [x] (not (divisible? x (stream-car stream))))
(stream-cdr stream)))))
;;(def primes (sieve (integers-starting-from 2)))
(def ones (cons-stream 1 ones))
(defn add-streams [s1 s2]
(stream-map + s1 s2))
(def integers (cons-stream 1 (add-streams ones integers)))
(def fibs (cons-stream 0 (cons-stream 1 (add-streams (stream-cdr fibs) fibs))))
(defn scale-stream [stream factor]
(stream-map (fn [x] (* x factor)) stream))
(def my-double (cons-stream 1 (scale-stream my-double 2)))
(declare prime?)
(def primes (cons-stream 2 (stream-filter prime? (integers-starting-from 3))))
(defn prime? [n]
(let [iter (fn iter [ps]
(cond (> (square (stream-car ps)) n) true
(divisible? n (stream-car ps)) false
:else (iter (stream-cdr ps))))]
(iter primes)))
(-> primes (stream-ref 50))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment