aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2020-07-30 13:28:35 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2020-07-30 13:28:35 +0200
commitcdd64714ad68980aaaa53bca0864d239cc2825ab (patch)
treeeeefeb0c5363c76677f2c693eebe3df56012d1a2
parentMake glob.scm use include#. (diff)
downloadcalp-cdd64714ad68980aaaa53bca0864d239cc2825ab.tar.gz
calp-cdd64714ad68980aaaa53bca0864d239cc2825ab.tar.xz
Add stream-paginate.
-rw-r--r--module/srfi/srfi-41/util.scm16
-rw-r--r--tests/srfi-41-util.scm35
2 files changed, 51 insertions, 0 deletions
diff --git a/module/srfi/srfi-41/util.scm b/module/srfi/srfi-41/util.scm
index 2da2b479..472170d7 100644
--- a/module/srfi/srfi-41/util.scm
+++ b/module/srfi/srfi-41/util.scm
@@ -86,6 +86,22 @@
(stream-map cadr (stream-filter car strm))
(stream-map cadr (stream-remove car strm)))))
+(define-public (stream-split idx stream)
+ (stream-cons (stream-take idx stream)
+ (stream-drop idx stream)))
+
+(define-stream (stream-paginate% stream page-size)
+ (stream-match (stream-split page-size stream)
+ ((page . rest)
+ (if (stream-null? page)
+ stream-null
+ (stream-cons
+ page
+ (stream-paginate rest page-size))))))
+
+(define*-public (stream-paginate stream optional: (page-size 10))
+ (stream-paginate% stream page-size))
+
;; Evaluates @var{body} in a context where most list fundamentals are
;; replaced by stream alternatives.
;; commented defifinitions are items which could be included, but for
diff --git a/tests/srfi-41-util.scm b/tests/srfi-41-util.scm
new file mode 100644
index 00000000..61bce71e
--- /dev/null
+++ b/tests/srfi-41-util.scm
@@ -0,0 +1,35 @@
+(((srfi srfi-41 util) stream-paginate)
+ ((srfi srfi-41) stream->list stream-ref stream-from
+ stream-filter stream-car stream)
+ ((ice-9 sandbox) call-with-time-limit)
+ )
+
+(test-equal "Finite stream"
+ '((0 1 2) (3 4 5) (6 7 8) (9))
+ (let ((strm
+ (stream-paginate (stream 0 1 2 3 4 5 6 7 8 9)
+ 3)))
+ (map stream->list (stream->list strm))))
+
+
+(test-equal "slice of infinite"
+ '(1000 1001 1002 1003 1004 1005 1006 1007 1008 1009)
+ (let ((strm (stream-paginate (stream-from 0))))
+ (stream->list (stream-ref strm 100))))
+
+
+
+(define unique-symbol (gensym))
+
+(test-equal "time out on infinite 'empty' stream"
+ unique-symbol
+ ;; defined outside time limit since creation should always
+ ;; succeed. Only reference is expected to fail.
+ (let ((strm (stream-paginate
+ ;; easy way to get stream which never finds
+ ;; any elements.
+ (stream-filter negative? (stream-from 0)))))
+ (call-with-time-limit
+ 0.1
+ (lambda () (stream-car strm))
+ (lambda _ unique-symbol))))