annotate src/clojure/contrib/test_contrib/stream_utils/examples.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@10 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@10 3 ;;
rlm@10 4 ;; Stream application examples
rlm@10 5 ;;
rlm@10 6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@10 7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@10 8
rlm@10 9 (ns
rlm@10 10 #^{:author "Konrad Hinsen"
rlm@10 11 :skip-wiki true
rlm@10 12 :doc "Examples for data streams"}
rlm@10 13 clojure.contrib.stream-utils.examples
rlm@10 14 (:refer-clojure :exclude (deftype))
rlm@10 15 (:use [clojure.contrib.stream-utils
rlm@10 16 :only (defst stream-next
rlm@10 17 pick pick-all
rlm@10 18 stream-type defstream
rlm@10 19 stream-drop stream-map stream-filter stream-flatten)])
rlm@10 20 (:use [clojure.contrib.monads :only (domonad)])
rlm@10 21 (:use [clojure.contrib.types :only (deftype)])
rlm@10 22 (:require [clojure.contrib.generic.collection :as gc]))
rlm@10 23
rlm@10 24 ;
rlm@10 25 ; Define a stream of Fibonacci numbers
rlm@10 26 ;
rlm@10 27 (deftype ::fib-stream last-two-fib)
rlm@10 28
rlm@10 29 (defstream ::fib-stream
rlm@10 30 [fs]
rlm@10 31 (let [[n1 n2] fs]
rlm@10 32 [n1 (last-two-fib [n2 (+ n1 n2)])]))
rlm@10 33
rlm@10 34 (def fib-stream (last-two-fib [0 1]))
rlm@10 35
rlm@10 36 (take 10 (gc/seq fib-stream))
rlm@10 37
rlm@10 38 ;
rlm@10 39 ; A simple random number generator, implemented as a stream
rlm@10 40 ;
rlm@10 41 (deftype ::random-seed rng-seed vector seq)
rlm@10 42
rlm@10 43 (defstream ::random-seed
rlm@10 44 [seed]
rlm@10 45 (let [[seed] seed
rlm@10 46 m 259200
rlm@10 47 value (/ (float seed) (float m))
rlm@10 48 next (rem (+ 54773 (* 7141 seed)) m)]
rlm@10 49 [value (rng-seed next)]))
rlm@10 50
rlm@10 51 (take 10 (gc/seq (rng-seed 1)))
rlm@10 52
rlm@10 53 ;
rlm@10 54 ; Various stream utilities
rlm@10 55 ;
rlm@10 56 (take 10 (gc/seq (stream-drop 10 (rng-seed 1))))
rlm@10 57 (gc/seq (stream-map inc (range 5)))
rlm@10 58 (gc/seq (stream-filter odd? (range 10)))
rlm@10 59 (gc/seq (stream-flatten (partition 3 (range 9))))
rlm@10 60
rlm@10 61 ;
rlm@10 62 ; Stream transformers
rlm@10 63 ;
rlm@10 64
rlm@10 65 ; Transform a stream of numbers into a stream of sums of two
rlm@10 66 ; consecutive numbers.
rlm@10 67 (defst sum-two [] [xs]
rlm@10 68 (domonad
rlm@10 69 [x1 (pick xs)
rlm@10 70 x2 (pick xs)]
rlm@10 71 (+ x1 x2)))
rlm@10 72
rlm@10 73 (def s (sum-two '(1 2 3 4 5 6 7 8)))
rlm@10 74
rlm@10 75 (let [[v1 s] (stream-next s)]
rlm@10 76 (let [[v2 s] (stream-next s)]
rlm@10 77 (let [[v3 s] (stream-next s)]
rlm@10 78 (let [[v4 s] (stream-next s)]
rlm@10 79 (let [[v5 s] (stream-next s)]
rlm@10 80 [v1 v2 v3 v4 v5])))))
rlm@10 81
rlm@10 82 (gc/seq s)
rlm@10 83
rlm@10 84 ; Map (for a single stream) written as a stream transformer
rlm@10 85 (defst my-map-1 [f] [xs]
rlm@10 86 (domonad
rlm@10 87 [x (pick xs)]
rlm@10 88 (f x)))
rlm@10 89
rlm@10 90 (gc/seq (my-map-1 inc [1 2 3]))
rlm@10 91
rlm@10 92 ; Map for two stream arguments
rlm@10 93 (defst my-map-2 [f] [xs ys]
rlm@10 94 (domonad
rlm@10 95 [x (pick xs)
rlm@10 96 y (pick ys)]
rlm@10 97 (f x y)))
rlm@10 98
rlm@10 99 (gc/seq (my-map-2 + '(1 2 3 4) '(10 20 30 40)))
rlm@10 100
rlm@10 101 ; Map for any number of stream arguments
rlm@10 102 (defst my-map [f] [& streams]
rlm@10 103 (domonad
rlm@10 104 [vs pick-all]
rlm@10 105 (apply f vs)))
rlm@10 106
rlm@10 107 (gc/seq (my-map inc [1 2 3]))
rlm@10 108 (gc/seq (my-map + '(1 2 3 4) '(10 20 30 40)))
rlm@10 109
rlm@10 110 ; Filter written as a stream transformer
rlm@10 111 (defst my-filter [p] [xs]
rlm@10 112 (domonad
rlm@10 113 [x (pick xs) :when (p x)]
rlm@10 114 x))
rlm@10 115
rlm@10 116 (gc/seq (my-filter odd? [1 2 3]))
rlm@10 117