Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Generalize `X-take-list' functions to `X-take'.

    `in-take-list' ==> `in-take'
`filter-take-list' ==> `filter-take'

In other words, they work on any sequence: list, vector, string, etc.
  • Loading branch information...
commit 5dd972c24a21325b85d7514f9e04dbf0d3dc2338 1 parent 190b89f
@greghendershott authored
Showing with 56 additions and 55 deletions.
  1. +2 −2 glacier.rkt
  2. +51 −50 take-list.rkt → take.rkt
  3. +3 −3 util.rkt
View
4 glacier.rkt
@@ -8,7 +8,7 @@
"keys.rkt"
"util.rkt"
"sigv4.rkt"
- "take-list.rkt"
+ "take.rkt"
)
(provide region
@@ -497,7 +497,7 @@
((listof sha256?) . -> . string?)
(match xs
[(list x) (bytes->hex-string x)]
- [else (hashes->tree (for/list ([(a b) (in-take-list xs 2 (const #f))])
+ [else (hashes->tree (for/list ([(a b) (in-take xs 2 (const #f))])
(cond [b (sha256 (bytes-append a b))]
[else a])))]))
View
101 take-list.rkt → take.rkt
@@ -1,7 +1,7 @@
#lang racket
-(provide in-take-list
- filter-take-list)
+(provide in-take
+ filter-take)
(module+ test
(require rackunit))
@@ -25,15 +25,13 @@
;; Although the motivation for this was lists of couples, it supports
;; triples, quadruples -- any group size.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; (in-take-list xs n) is a way to sequence a list `n' elements at a
-;; time from `xs'. For instance with n=2 you will get successive
-;; couples of elements, with n=3 you get triples, and so on. `n'
-;; defaults to 2. If there aren't exactly `n' elements at the end of
-;; the list, `fill' is called. `fill' defaults to a procedure that
-;; raises an error, but you may supply a procedure that "fills in
-;; missing values".
+;; (in-take seq n) is a way to take `n' elements at a time from
+;; `seq'. For instance with n=2 you will get successive couples of
+;; elements, with n=3 you get triples, and so on. `n' defaults to 2.
+;; If there aren't exactly `n' elements at the end of the list, `fill'
+;; is called. `fill' defaults to a procedure that raises an error, but
+;; you may supply a procedure that "fills in missing values".
(struct
take-list-iterator (xs n fill)
@@ -65,65 +63,68 @@
(define fill/c (exact-nonnegative-integer? . -> . any/c))
-(define/contract (in-take-list xs [n 2] [fill (make-fill 'in-take-list n)])
- ((list?) (exact-positive-integer? fill/c) . ->* . take-list?)
- (take-list xs n fill))
+(define/contract (in-take seq [n 2] [fill (make-fill 'in-take-list n)])
+ ((sequence?) (exact-positive-integer? fill/c) . ->* . take-list?)
+ (take-list (sequence->list seq) n fill))
(module+ test
(test-case
- "in-take-list"
- ;; Test list is multiple of take size
- (check-equal?
- (for/list ([(k v) (in-take-list (list 'a "1" 'b "2"))])
- (cons k v))
- '([a . "1"][b . "2"]))
- ;; Test missing values raising an error (the default)
- (check-exn
- exn:fail?
- (lambda () (for/list ([(k v) (in-take-list '(a "1" b "2" c) 2)])
- (cons k v))))
- ;; Test missing values filled in
- (check-equal?
- (for/list ([(k v) (in-take-list '(a "1" b "2" c) 2 (const "FILL"))])
- (cons k v))
- '([a . "1"][b . "2"][c . "FILL"]))
- ;; Test fill function passed expected "index"
- (check-equal?
- (for/list ([(a b c d e) (in-take-list '(0 1) 5 values)])
- (list a b c d e))
- '((0 1 2 3 4))) ;fill was called with 2 3 4
- ;; Test taking the same list with different take-sizes.
- (define (test-take-lists xs n)
- (for/list ([ts (in-values-sequence (in-take-list xs n))])
- ts))
+ "in-take"
+ ;; Sequence is multiple of take size
+ (check-equal? (for/list ([(k v) (in-take (list 'a "1" 'b "2"))])
+ (cons k v))
+ '([a . "1"][b . "2"]))
+ (check-equal? (for/list ([(k v) (in-take (vector 'a "1" 'b "2"))])
+ (cons k v))
+ '([a . "1"][b . "2"]))
+ (check-equal? (for/list ([(k v) (in-take "a1b2")])
+ (cons k v))
+ '([#\a . #\1][#\b . #\2]))
+ ;; Missing values raising an error (the default `fill')
+ (check-exn exn:fail?
+ (lambda () (for/list ([(k v) (in-take '(a "1" b "2" c) 2)])
+ (cons k v))))
+ ;; Missing values filled in
+ (check-equal? (for/list ([(k v) (in-take '(a "1" b "2" c) 2
+ (const "FILL"))])
+ (cons k v))
+ '([a . "1"][b . "2"][c . "FILL"]))
+ ;; Fill function is passed expected "index"
+ (check-equal? (for/list ([(a b c d e) (in-take '(0 1) 5 values)])
+ (list a b c d e))
+ '((0 1 2 3 4))) ;fill was called with 2 3 4
+ ;; Taking the same list with different take-sizes.
(define test-xs (list 0 1 2 3 4 5 6 7 8 9))
- (check-equal? (test-take-lists test-xs 1)
+ (define (test-take n)
+ (for/list ([ts (in-values-sequence (in-take test-xs n))])
+ ts))
+ (check-equal? (test-take 1)
'((0) (1) (2) (3) (4) (5) (6) (7) (8) (9)))
- (check-equal? (test-take-lists test-xs 2)
+ (check-equal? (test-take 2)
'((0 1) (2 3) (4 5) (6 7) (8 9)))
- (check-equal? (test-take-lists test-xs 5)
+ (check-equal? (test-take 5)
'((0 1 2 3 4) (5 6 7 8 9)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Given a list `xs', return a similarly flat list containing only
-;; each `n' elements for which `pred?' is true.
+;; Given a sequence, return a sequence containing only each group of `n'
+;; elements for which `pred?' is true.
-(define/contract (filter-take-list pred? xs [n 2]
- [fill (make-fill 'in-take n)])
- ((procedure? list?) (exact-positive-integer? fill/c) . ->* . list?)
+(define/contract (filter-take pred? seq [n 2]
+ [fill (make-fill 'in-take n)])
+ ((procedure? sequence?) (exact-positive-integer? fill/c) . ->* . list?)
(for/fold ([ys '()])
- ([ts (in-values-sequence (in-take-list xs n fill))])
+ ([ts (in-values-sequence (in-take seq n fill))])
(cond [(apply pred? ts) (append ys ts)]
[else ys])))
(module+ test
(test-case
"filter-take-list"
- (check-equal? (filter-take-list (lambda (a b) b) '(a 1 b #f c 3) 2)
+ (check-equal? (filter-take (lambda (a b) b) '(a 1 b #f c 3) 2)
'(a 1 c 3))
- (check-equal? (filter-take-list (const #f) '(1 2 3 4) 2) '())
- (check-equal? (filter-take-list (const #t) '() 2) '())))
+ (check-equal? (filter-take (const #f) '(1 2 3 4) 2) '())
+ (check-equal? (filter-take (const #t) '() 2) '())))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
View
6 util.rkt
@@ -183,13 +183,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(require "take-list.rkt")
+(require "take.rkt")
;; Much like `hash' lets you supply the pairs as a flat list, `alist'
;; lets you do so for an association list. Saves some tedious typing
;; of parens and dots.
(define/provide (alist . xs)
- (for/list ([(k v) (in-take-list xs 2)])
+ (for/list ([(k v) (in-take xs 2)])
(cons k v)))
(module+ test
@@ -200,7 +200,7 @@
;; Given a list of couples k0 v0 k1 v1 ... kN vN, return the k v couples
;; where v is not #f.
(define/provide (true-value-pairs . xs)
- (filter-take-list (lambda (k v) v) xs))
+ (filter-take (lambda (k v) v) xs))
(module+ test
(check-equal? (true-value-pairs 'a 1 'b #f 'c 2)
Please sign in to comment.
Something went wrong with that request. Please try again.