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