git.iko.soy/rowtype-yoga/purescm
on bytevector help sign in
8 files changed+659−105
since splitsnapshots
unifiedsplit
lib/purescm/bytevector.ss+244 lib/purescm/test/bytevector-test.ss+307 package-lock.json+2−2 package-sets/1.0.0.json+26−26 package.json+1−1 spago.yaml+1−1 test-runtime.ss+4−1 test-snapshots/spago.lock+74−74
lib/purescm/bytevector.ssnew file+244
@@ -0,0 +1,244 @@
1+#!chezscheme
2+(library (purescm bytevector)
3+ (export
4+ ;; Construction
5+ bytevector-make
6+
7+ ;; Pure accessors (curried for PureScript calling convention)
8+ bv-length
9+ bv-ref
10+ bv-set
11+
12+ ;; Slicing / concatenation
13+ bv-slice
14+ bv-concat
15+
16+ ;; Equality / comparison
17+ bv-eq?
18+ bv-compare
19+
20+ ;; Conversion: flexvector <-> bytevector
21+ bv-from-flexvector
22+ bv-to-flexvector
23+
24+ ;; Conversion: native Chez string <-> bytevector (UTF-8)
25+ ;; NOTE: These work with native Chez strings, NOT pstrings.
26+ ;; In PureScript FFI .ss files, wrap with rt:pstring->string / rt:string->pstring
27+ bv-from-utf8
28+ bv-to-utf8
29+
30+ ;; Hex encoding (native Chez strings — same wrapping needed at FFI boundary)
31+ bv-to-hex
32+ bv-from-hex
33+
34+ ;; Mutation primitives (for Effect-based APIs)
35+ bv-copy-into!
36+ bv-xor-into!
37+ bv-fill!)
38+
39+ (import
40+ (chezscheme)
41+ (prefix (srfi :214) fv:))
42+
43+ ;; ------------------------------------------------------------------
44+ ;; Construction
45+ ;; ------------------------------------------------------------------
46+
47+ (define bytevector-make
48+ (lambda (n) (make-bytevector n 0)))
49+
50+ ;; ------------------------------------------------------------------
51+ ;; Pure accessors (curried for PureScript calling convention)
52+ ;; ------------------------------------------------------------------
53+
54+ (define bv-length bytevector-length)
55+
56+ ;; ByteArray -> Int -> Int
57+ (define bv-ref
58+ (lambda (bv)
59+ (lambda (i)
60+ (bytevector-u8-ref bv i))))
61+
62+ ;; Pure set: returns a fresh copy with one byte changed.
63+ ;; ByteArray -> Int -> Int -> ByteArray
64+ (define bv-set
65+ (lambda (bv)
66+ (lambda (i)
67+ (lambda (val)
68+ (let ([out (bytevector-copy bv)])
69+ (bytevector-u8-set! out i val)
70+ out)))))
71+
72+ ;; ------------------------------------------------------------------
73+ ;; Slicing / concatenation
74+ ;; ------------------------------------------------------------------
75+
76+ ;; Int -> Int -> ByteArray -> ByteArray
77+ (define bv-slice
78+ (lambda (start)
79+ (lambda (end)
80+ (lambda (bv)
81+ (let* ([len (fx- end start)]
82+ [out (make-bytevector len)])
83+ (bytevector-copy! bv start out 0 len)
84+ out)))))
85+
86+ ;; ByteArray -> ByteArray -> ByteArray
87+ (define bv-concat
88+ (lambda (a)
89+ (lambda (b)
90+ (let* ([la (bytevector-length a)]
91+ [lb (bytevector-length b)]
92+ [out (make-bytevector (fx+ la lb))])
93+ (bytevector-copy! a 0 out 0 la)
94+ (bytevector-copy! b 0 out la lb)
95+ out))))
96+
97+ ;; ------------------------------------------------------------------
98+ ;; Equality / comparison
99+ ;; ------------------------------------------------------------------
100+
101+ ;; ByteArray -> ByteArray -> Boolean
102+ (define bv-eq?
103+ (lambda (a)
104+ (lambda (b)
105+ (bytevector=? a b))))
106+
107+ ;; Lexicographic comparison, returns -1 / 0 / 1.
108+ ;; ByteArray -> ByteArray -> Int
109+ (define bv-compare
110+ (lambda (a)
111+ (lambda (b)
112+ (let ([la (bytevector-length a)]
113+ [lb (bytevector-length b)])
114+ (let loop ([i 0])
115+ (cond
116+ [(and (fx= i la) (fx= i lb)) 0]
117+ [(fx= i la) -1]
118+ [(fx= i lb) 1]
119+ [else
120+ (let ([ba (bytevector-u8-ref a i)]
121+ [bb (bytevector-u8-ref b i)])
122+ (cond
123+ [(fx<? ba bb) -1]
124+ [(fx>? ba bb) 1]
125+ [else (loop (fx+ i 1))]))]))))))
126+
127+ ;; ------------------------------------------------------------------
128+ ;; Conversion: flexvector (PureScript Array Int) <-> bytevector
129+ ;; ------------------------------------------------------------------
130+
131+ ;; Array Int -> ByteArray
132+ (define bv-from-flexvector
133+ (lambda (fv)
134+ (let* ([n (fv:flexvector-length fv)]
135+ [bv (make-bytevector n)])
136+ (do ([i 0 (fx+ i 1)])
137+ ((fx= i n) bv)
138+ (bytevector-u8-set! bv i
139+ (fxlogand (fv:flexvector-ref fv i) #xFF))))))
140+
141+ ;; ByteArray -> Array Int
142+ (define bv-to-flexvector
143+ (lambda (bv)
144+ (let* ([n (bytevector-length bv)]
145+ [fv (fv:make-flexvector n 0)])
146+ (do ([i 0 (fx+ i 1)])
147+ ((fx= i n) fv)
148+ (fv:flexvector-set! fv i (bytevector-u8-ref bv i))))))
149+
150+ ;; ------------------------------------------------------------------
151+ ;; Conversion: native Chez string <-> bytevector (UTF-8)
152+ ;; ------------------------------------------------------------------
153+
154+ ;; Native Chez String -> ByteArray
155+ (define bv-from-utf8
156+ (lambda (s)
157+ (string->utf8 s)))
158+
159+ ;; ByteArray -> Native Chez String
160+ (define bv-to-utf8
161+ (lambda (bv)
162+ (utf8->string bv)))
163+
164+ ;; ------------------------------------------------------------------
165+ ;; Hex encoding (native Chez strings)
166+ ;; ------------------------------------------------------------------
167+
168+ (define hex-chars "0123456789abcdef")
169+
170+ ;; ByteArray -> Native Chez String
171+ (define bv-to-hex
172+ (lambda (bv)
173+ (let* ([n (bytevector-length bv)]
174+ [out (make-string (fx* n 2))])
175+ (do ([i 0 (fx+ i 1)])
176+ ((fx= i n) out)
177+ (let ([b (bytevector-u8-ref bv i)])
178+ (string-set! out (fx* i 2)
179+ (string-ref hex-chars (fxsrl b 4)))
180+ (string-set! out (fx+ (fx* i 2) 1)
181+ (string-ref hex-chars (fxlogand b #xF))))))))
182+
183+ (define hex-val
184+ (lambda (c)
185+ (let ([cp (char->integer c)])
186+ (cond
187+ [(fx<=? 48 cp 57) (fx- cp 48)] ;; 0-9
188+ [(fx<=? 97 cp 102) (fx- cp 87)] ;; a-f
189+ [(fx<=? 65 cp 70) (fx- cp 55)] ;; A-F
190+ [else (error 'hex-val "invalid hex digit" c)]))))
191+
192+ ;; Native Chez String -> ByteArray
193+ (define bv-from-hex
194+ (lambda (s)
195+ (let* ([slen (string-length s)]
196+ [n (fxsrl slen 1)]
197+ [bv (make-bytevector n)])
198+ (do ([i 0 (fx+ i 1)])
199+ ((fx= i n) bv)
200+ (let ([hi (hex-val (string-ref s (fx* i 2)))]
201+ [lo (hex-val (string-ref s (fx+ (fx* i 2) 1)))])
202+ (bytevector-u8-set! bv i
203+ (fxlogor (fxsll hi 4) lo)))))))
204+
205+ ;; ------------------------------------------------------------------
206+ ;; Mutation primitives (for Effect-based PureScript APIs)
207+ ;; ------------------------------------------------------------------
208+
209+ ;; ByteArray -> Int -> ByteArray -> Int -> Int -> Unit
210+ (define bv-copy-into!
211+ (lambda (src)
212+ (lambda (src-off)
213+ (lambda (dst)
214+ (lambda (dst-off)
215+ (lambda (len)
216+ (bytevector-copy! src src-off dst dst-off len)))))))
217+
218+ ;; ByteArray -> Int -> ByteArray -> Int -> Int -> Unit
219+ (define bv-xor-into!
220+ (lambda (dst)
221+ (lambda (dst-off)
222+ (lambda (src)
223+ (lambda (src-off)
224+ (lambda (len)
225+ (do ([i 0 (fx+ i 1)])
226+ ((fx= i len))
227+ (let ([di (fx+ dst-off i)]
228+ [si (fx+ src-off i)])
229+ (bytevector-u8-set! dst di
230+ (fxlogxor
231+ (bytevector-u8-ref dst di)
232+ (bytevector-u8-ref src si)))))))))))
233+
234+ ;; ByteArray -> Int -> Int -> Int -> Unit
235+ (define bv-fill!
236+ (lambda (bv)
237+ (lambda (off)
238+ (lambda (len)
239+ (lambda (val)
240+ (do ([i 0 (fx+ i 1)])
241+ ((fx= i len))
242+ (bytevector-u8-set! bv (fx+ off i) val)))))))
243+
244+) ;; end library
lib/purescm/test/bytevector-test.ssnew file+307
@@ -0,0 +1,307 @@
1+(library (purescm test bytevector-test)
2+ (export main)
3+ (import (chezscheme)
4+ (prefix (srfi :214) fv:)
5+ (purescm bytevector))
6+
7+ (define (assert-true msg v)
8+ (unless v
9+ (error 'bytevector-test (format "FAIL: ~a" msg))))
10+
11+ (define main
12+ (lambda ()
13+
14+ ;; ============================================================
15+ ;; Construction
16+ ;; ============================================================
17+
18+ (assert-true "make 0" (bytevector? (bytevector-make 0)))
19+ (assert-true "make 0 length" (fx=? 0 (bv-length (bytevector-make 0))))
20+ (assert-true "make 16 length" (fx=? 16 (bv-length (bytevector-make 16))))
21+
22+ (let ([bv (bytevector-make 4)])
23+ (assert-true "zero-init 0" (fx=? 0 ((bv-ref bv) 0)))
24+ (assert-true "zero-init 3" (fx=? 0 ((bv-ref bv) 3))))
25+
26+ (display " ✓ construction\n")
27+
28+ ;; ============================================================
29+ ;; Ref / set (pure, copy-on-write)
30+ ;; ============================================================
31+
32+ (let* ([bv (bytevector-make 3)]
33+ [bv2 (((bv-set bv) 1) 42)])
34+ (assert-true "set: original unchanged" (fx=? 0 ((bv-ref bv) 1)))
35+ (assert-true "set: copy updated" (fx=? 42 ((bv-ref bv2) 1)))
36+ (assert-true "set: other bytes 0" (fx=? 0 ((bv-ref bv2) 0)))
37+ (assert-true "set: other bytes 2" (fx=? 0 ((bv-ref bv2) 2))))
38+
39+ (display " ✓ ref / set (pure)\n")
40+
41+ ;; ============================================================
42+ ;; Slice
43+ ;; ============================================================
44+
45+ (let* ([bv (bv-from-flexvector (fv:flexvector 10 20 30 40 50))]
46+ [sl (((bv-slice 1) 4) bv)])
47+ (assert-true "slice length" (fx=? 3 (bv-length sl)))
48+ (assert-true "slice [0]" (fx=? 20 ((bv-ref sl) 0)))
49+ (assert-true "slice [1]" (fx=? 30 ((bv-ref sl) 1)))
50+ (assert-true "slice [2]" (fx=? 40 ((bv-ref sl) 2))))
51+
52+ (let ([sl (((bv-slice 2) 2) (bytevector-make 5))])
53+ (assert-true "empty slice" (fx=? 0 (bv-length sl))))
54+
55+ (display " ✓ slice\n")
56+
57+ ;; ============================================================
58+ ;; Concat
59+ ;; ============================================================
60+
61+ (let* ([a (bv-from-flexvector (fv:flexvector 1 2 3))]
62+ [b (bv-from-flexvector (fv:flexvector 4 5))]
63+ [c ((bv-concat a) b)])
64+ (assert-true "concat length" (fx=? 5 (bv-length c)))
65+ (assert-true "concat [0]" (fx=? 1 ((bv-ref c) 0)))
66+ (assert-true "concat [2]" (fx=? 3 ((bv-ref c) 2)))
67+ (assert-true "concat [3]" (fx=? 4 ((bv-ref c) 3)))
68+ (assert-true "concat [4]" (fx=? 5 ((bv-ref c) 4))))
69+
70+ (let* ([a (bv-from-flexvector (fv:flexvector 1 2))]
71+ [e (bytevector-make 0)])
72+ (assert-true "concat a+empty" (fx=? 2 (bv-length ((bv-concat a) e))))
73+ (assert-true "concat empty+a" (fx=? 2 (bv-length ((bv-concat e) a)))))
74+
75+ (display " ✓ concat\n")
76+
77+ ;; ============================================================
78+ ;; Equality
79+ ;; ============================================================
80+
81+ (assert-true "eq empty" ((bv-eq? (bytevector-make 0)) (bytevector-make 0)))
82+ (assert-true "eq same"
83+ ((bv-eq? (bv-from-flexvector (fv:flexvector 1 2 3)))
84+ (bv-from-flexvector (fv:flexvector 1 2 3))))
85+ (assert-true "neq value"
86+ (not ((bv-eq? (bv-from-flexvector (fv:flexvector 1 2 3)))
87+ (bv-from-flexvector (fv:flexvector 1 2 4)))))
88+ (assert-true "neq length"
89+ (not ((bv-eq? (bv-from-flexvector (fv:flexvector 1 2)))
90+ (bv-from-flexvector (fv:flexvector 1 2 3)))))
91+
92+ (display " ✓ equality\n")
93+
94+ ;; ============================================================
95+ ;; Compare (lexicographic)
96+ ;; ============================================================
97+
98+ (assert-true "cmp empty=empty"
99+ (fx=? 0 ((bv-compare (bytevector-make 0)) (bytevector-make 0))))
100+ (assert-true "cmp equal"
101+ (fx=? 0 ((bv-compare (bv-from-flexvector (fv:flexvector 1 2)))
102+ (bv-from-flexvector (fv:flexvector 1 2)))))
103+ (assert-true "cmp less-by-value"
104+ (fx=? -1 ((bv-compare (bv-from-flexvector (fv:flexvector 1 2)))
105+ (bv-from-flexvector (fv:flexvector 1 3)))))
106+ (assert-true "cmp greater-by-value"
107+ (fx=? 1 ((bv-compare (bv-from-flexvector (fv:flexvector 1 3)))
108+ (bv-from-flexvector (fv:flexvector 1 2)))))
109+ (assert-true "cmp shorter<longer"
110+ (fx=? -1 ((bv-compare (bv-from-flexvector (fv:flexvector 1 2)))
111+ (bv-from-flexvector (fv:flexvector 1 2 3)))))
112+
113+ (display " ✓ compare\n")
114+
115+ ;; ============================================================
116+ ;; Flexvector round-trip
117+ ;; ============================================================
118+
119+ (let* ([fv (fv:flexvector 0 127 128 255)]
120+ [bv (bv-from-flexvector fv)]
121+ [fv2 (bv-to-flexvector bv)])
122+ (assert-true "fv->bv length" (fx=? 4 (bv-length bv)))
123+ (assert-true "fv->bv [0]" (fx=? 0 ((bv-ref bv) 0)))
124+ (assert-true "fv->bv [1]" (fx=? 127 ((bv-ref bv) 1)))
125+ (assert-true "fv->bv [2]" (fx=? 128 ((bv-ref bv) 2)))
126+ (assert-true "fv->bv [3]" (fx=? 255 ((bv-ref bv) 3)))
127+ (assert-true "bv->fv length" (fx=? 4 (fv:flexvector-length fv2)))
128+ (assert-true "bv->fv [0]" (fx=? 0 (fv:flexvector-ref fv2 0)))
129+ (assert-true "bv->fv [3]" (fx=? 255 (fv:flexvector-ref fv2 3))))
130+
131+ ;; Values > 255 get masked to low byte
132+ (let* ([fv (fv:flexvector 256 511)]
133+ [bv (bv-from-flexvector fv)])
134+ (assert-true "mask 256->0" (fx=? 0 ((bv-ref bv) 0)))
135+ (assert-true "mask 511->255" (fx=? 255 ((bv-ref bv) 1))))
136+
137+ (display " ✓ flexvector round-trip\n")
138+
139+ ;; ============================================================
140+ ;; String <-> bytevector (UTF-8) — using native Chez strings
141+ ;; ============================================================
142+
143+ (let ([bv (bv-from-utf8 "abc")])
144+ (assert-true "str->bv length" (fx=? 3 (bv-length bv)))
145+ (assert-true "str->bv a" (fx=? 97 ((bv-ref bv) 0)))
146+ (assert-true "str->bv b" (fx=? 98 ((bv-ref bv) 1)))
147+ (assert-true "str->bv c" (fx=? 99 ((bv-ref bv) 2))))
148+
149+ ;; Multi-byte UTF-8
150+ (let ([bv (bv-from-utf8 "ä")])
151+ (assert-true "str->bv ä length" (fx=? 2 (bv-length bv)))
152+ (assert-true "str->bv ä [0]" (fx=? #xC3 ((bv-ref bv) 0)))
153+ (assert-true "str->bv ä [1]" (fx=? #xA4 ((bv-ref bv) 1))))
154+
155+ (assert-true "str->bv empty" (fx=? 0 (bv-length (bv-from-utf8 ""))))
156+
157+ ;; Round-trip
158+ (let* ([s "hello 🌍"]
159+ [bv (bv-from-utf8 s)]
160+ [s2 (bv-to-utf8 bv)])
161+ (assert-true "str round-trip" (string=? s s2)))
162+
163+ (display " ✓ string <-> bytevector (UTF-8)\n")
164+
165+ ;; ============================================================
166+ ;; Hex round-trip — using native Chez strings
167+ ;; ============================================================
168+
169+ (let* ([bv (bv-from-flexvector (fv:flexvector 0 1 15 16 255))]
170+ [hex (bv-to-hex bv)])
171+ (assert-true "to-hex" (string=? hex "00010f10ff"))
172+ (assert-true "hex round-trip" ((bv-eq? bv) (bv-from-hex hex))))
173+
174+ (let ([hex (bv-to-hex (bytevector-make 0))])
175+ (assert-true "hex empty" (string=? hex ""))
176+ (assert-true "hex empty round" (fx=? 0 (bv-length (bv-from-hex hex)))))
177+
178+ ;; Upper-case hex input
179+ (let ([bv (bv-from-hex "DEADBEEF")])
180+ (assert-true "hex upper length" (fx=? 4 (bv-length bv)))
181+ (assert-true "hex upper [0]" (fx=? #xDE ((bv-ref bv) 0)))
182+ (assert-true "hex upper [1]" (fx=? #xAD ((bv-ref bv) 1)))
183+ (assert-true "hex upper [2]" (fx=? #xBE ((bv-ref bv) 2)))
184+ (assert-true "hex upper [3]" (fx=? #xEF ((bv-ref bv) 3))))
185+
186+ (display " ✓ hex round-trip\n")
187+
188+ ;; ============================================================
189+ ;; Mutation: bv-copy-into!
190+ ;; ============================================================
191+
192+ (let ([src (bv-from-flexvector (fv:flexvector 10 20 30 40 50))]
193+ [dst (bytevector-make 8)])
194+ (((((bv-copy-into! src) 1) dst) 2) 3)
195+ (assert-true "copy dst[0]" (fx=? 0 ((bv-ref dst) 0)))
196+ (assert-true "copy dst[1]" (fx=? 0 ((bv-ref dst) 1)))
197+ (assert-true "copy dst[2]" (fx=? 20 ((bv-ref dst) 2)))
198+ (assert-true "copy dst[3]" (fx=? 30 ((bv-ref dst) 3)))
199+ (assert-true "copy dst[4]" (fx=? 40 ((bv-ref dst) 4)))
200+ (assert-true "copy dst[5]" (fx=? 0 ((bv-ref dst) 5))))
201+
202+ (display " ✓ bv-copy-into!\n")
203+
204+ ;; ============================================================
205+ ;; Mutation: bv-xor-into!
206+ ;; ============================================================
207+
208+ (let ([dst (bv-from-flexvector (fv:flexvector #xFF #x00 #xAA #x55))]
209+ [src (bv-from-flexvector (fv:flexvector #xFF #xFF #x55 #xAA))])
210+ (((((bv-xor-into! dst) 0) src) 0) 4)
211+ (assert-true "xor [0]" (fx=? #x00 ((bv-ref dst) 0)))
212+ (assert-true "xor [1]" (fx=? #xFF ((bv-ref dst) 1)))
213+ (assert-true "xor [2]" (fx=? #xFF ((bv-ref dst) 2)))
214+ (assert-true "xor [3]" (fx=? #xFF ((bv-ref dst) 3))))
215+
216+ (let ([dst (bv-from-flexvector (fv:flexvector 0 0 0 0))]
217+ [src (bv-from-flexvector (fv:flexvector #xAA #xBB))])
218+ (((((bv-xor-into! dst) 1) src) 0) 2)
219+ (assert-true "xor offset [0]" (fx=? #x00 ((bv-ref dst) 0)))
220+ (assert-true "xor offset [1]" (fx=? #xAA ((bv-ref dst) 1)))
221+ (assert-true "xor offset [2]" (fx=? #xBB ((bv-ref dst) 2)))
222+ (assert-true "xor offset [3]" (fx=? #x00 ((bv-ref dst) 3))))
223+
224+ (display " ✓ bv-xor-into!\n")
225+
226+ ;; ============================================================
227+ ;; Mutation: bv-fill!
228+ ;; ============================================================
229+
230+ (let ([bv (bytevector-make 5)])
231+ ((((bv-fill! bv) 1) 3) #xCC)
232+ (assert-true "fill [0]" (fx=? #x00 ((bv-ref bv) 0)))
233+ (assert-true "fill [1]" (fx=? #xCC ((bv-ref bv) 1)))
234+ (assert-true "fill [2]" (fx=? #xCC ((bv-ref bv) 2)))
235+ (assert-true "fill [3]" (fx=? #xCC ((bv-ref bv) 3)))
236+ (assert-true "fill [4]" (fx=? #x00 ((bv-ref bv) 4))))
237+
238+ (display " ✓ bv-fill!\n")
239+
240+ ;; ============================================================
241+ ;; Benchmark: bytevector vs flexvector XOR throughput
242+ ;; ============================================================
243+
244+ (display "\n Benchmarks:\n")
245+
246+ (let* ([size (* 1024 1024)]
247+ [iterations 20])
248+
249+ ;; --- Bytevector XOR ---
250+ (let ([a (bytevector-make size)]
251+ [b (bytevector-make size)])
252+ (do ([i 0 (fx+ i 1)]) ((fx= i size))
253+ (bytevector-u8-set! b i (fxlogand i #xFF)))
254+ (collect)
255+ (let ([t0 (current-time 'time-monotonic)])
256+ (do ([iter 0 (fx+ iter 1)]) ((fx= iter iterations))
257+ (((((bv-xor-into! a) 0) b) 0) size))
258+ (let* ([t1 (current-time 'time-monotonic)]
259+ [ns (+ (* (- (time-second t1) (time-second t0)) 1000000000)
260+ (- (time-nanosecond t1) (time-nanosecond t0)))]
261+ [total-mb (/ (* iterations size) 1048576.0)]
262+ [secs (/ ns 1000000000.0)]
263+ [mbps (/ total-mb secs)])
264+ (display (format " bytevector XOR: ~,1f MB/s (~a MiB x ~a iters)\n"
265+ mbps (/ size 1048576) iterations)))))
266+
267+ ;; --- Flexvector XOR ---
268+ (let ([a (fv:make-flexvector size 0)]
269+ [b (fv:make-flexvector size 0)])
270+ (do ([i 0 (fx+ i 1)]) ((fx= i size))
271+ (fv:flexvector-set! b i (fxlogand i #xFF)))
272+ (collect)
273+ (let ([t0 (current-time 'time-monotonic)])
274+ (do ([iter 0 (fx+ iter 1)]) ((fx= iter iterations))
275+ (do ([i 0 (fx+ i 1)]) ((fx= i size))
276+ (fv:flexvector-set! a i
277+ (fxlogxor (fv:flexvector-ref a i)
278+ (fv:flexvector-ref b i)))))
279+ (let* ([t1 (current-time 'time-monotonic)]
280+ [ns (+ (* (- (time-second t1) (time-second t0)) 1000000000)
281+ (- (time-nanosecond t1) (time-nanosecond t0)))]
282+ [total-mb (/ (* iterations size) 1048576.0)]
283+ [secs (/ ns 1000000000.0)]
284+ [mbps (/ total-mb secs)])
285+ (display (format " flexvector XOR: ~,1f MB/s (~a MiB x ~a iters)\n"
286+ mbps (/ size 1048576) iterations)))))
287+
288+ ;; --- Conversion cost ---
289+ (let ([fv (fv:make-flexvector size 0)])
290+ (do ([i 0 (fx+ i 1)]) ((fx= i size))
291+ (fv:flexvector-set! fv i (fxlogand i #xFF)))
292+ (collect)
293+ (let ([t0 (current-time 'time-monotonic)])
294+ (do ([iter 0 (fx+ iter 1)]) ((fx= iter 10))
295+ (bv-from-flexvector fv))
296+ (let* ([t1 (current-time 'time-monotonic)]
297+ [ns (+ (* (- (time-second t1) (time-second t0)) 1000000000)
298+ (- (time-nanosecond t1) (time-nanosecond t0)))]
299+ [total-mb (/ (* 10 size) 1048576.0)]
300+ [secs (/ ns 1000000000.0)]
301+ [mbps (/ total-mb secs)])
302+ (display (format " fv->bv convert: ~,1f MB/s (overhead you eliminate)\n"
303+ mbps))))))
304+
305+ (display "\n")
306+
307+ )))
package-lock.json+2−2
@@ -7,8 +7,8 @@
77 "bin": {
88 "purescm": "index.js"
99 },
10− "version": "1.11.0"
10+ "version": "1.12.0"
1111 }
1212 },
13− "version": "1.11.0"
13+ "version": "1.12.0"
1414}
package-sets/1.0.0.json+26−26
@@ -5,66 +5,66 @@
55 "packages": {
66 "arrays": {
77 "git": "https://github.com/purescm/purescript-core.git",
8− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
8+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
99 "subdir": "arrays"
1010 },
1111 "assert": {
1212 "git": "https://github.com/purescm/purescript-core.git",
13− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
13+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
1414 "subdir": "assert"
1515 },
1616 "bifunctors": "6.0.0",
1717 "catenable-lists": "7.0.0",
1818 "console": {
1919 "git": "https://github.com/purescm/purescript-core.git",
20− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
20+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
2121 "subdir": "console"
2222 },
2323 "const": "6.0.0",
2424 "contravariant": "6.0.0",
2525 "control": {
2626 "git": "https://github.com/purescm/purescript-core.git",
27− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
27+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
2828 "subdir": "control"
2929 },
3030 "datetime": {
3131 "git": "https://github.com/purescm/purescript-core.git",
32− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
32+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
3333 "subdir": "datetime"
3434 },
3535 "distributive": "6.0.0",
3636 "effect": {
3737 "git": "https://github.com/purescm/purescript-core.git",
38− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
38+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
3939 "subdir": "effect"
4040 },
4141 "either": "6.1.0",
4242 "enums": {
4343 "git": "https://github.com/purescm/purescript-core.git",
44− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
44+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
4545 "subdir": "enums"
4646 },
4747 "exceptions": {
4848 "git": "https://github.com/purescm/purescript-core.git",
49− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
49+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
5050 "subdir": "exceptions"
5151 },
5252 "exists": "6.0.0",
5353 "filterable": "5.0.0",
5454 "foldable-traversable": {
5555 "git": "https://github.com/purescm/purescript-core.git",
56− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
56+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
5757 "subdir": "foldable-traversable"
5858 },
5959 "foreign-object": {
6060 "git": "https://github.com/purescm/purescript-core.git",
61− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
61+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
6262 "subdir": "foreign-object"
6363 },
6464 "free": "7.1.0",
6565 "functions": {
6666 "git": "https://github.com/purescm/purescript-core.git",
67− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
67+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
6868 "subdir": "functions",
6969 "dependencies": [
7070 "prelude"
@@ -75,18 +75,18 @@
7575 "identity": "6.0.0",
7676 "integers": {
7777 "git": "https://github.com/purescm/purescript-core.git",
78− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
78+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
7979 "subdir": "integers"
8080 },
8181 "invariant": "6.0.0",
8282 "json": {
8383 "git": "https://github.com/purescm/purescript-core.git",
84− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
84+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
8585 "subdir": "json"
8686 },
8787 "lazy": {
8888 "git": "https://github.com/purescm/purescript-core.git",
89− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
89+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
9090 "subdir": "lazy"
9191 },
9292 "lcg": "4.0.0",
@@ -97,14 +97,14 @@
9797 "maybe": "6.0.0",
9898 "minibench": {
9999 "git": "https://github.com/purescm/purescript-core.git",
100− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
100+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
101101 "subdir": "minibench"
102102 },
103103 "newtype": "5.0.0",
104104 "nonempty": "7.0.0",
105105 "numbers": {
106106 "git": "https://github.com/purescm/purescript-core.git",
107− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
107+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
108108 "subdir": "numbers"
109109 },
110110 "ordered-collections": "3.1.1",
@@ -112,45 +112,45 @@
112112 "parallel": "7.0.0",
113113 "partial": {
114114 "git": "https://github.com/purescm/purescript-core.git",
115− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
115+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
116116 "subdir": "partial",
117117 "dependencies": []
118118 },
119119 "prelude": {
120120 "git": "https://github.com/purescm/purescript-core.git",
121− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
121+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
122122 "subdir": "prelude"
123123 },
124124 "profunctor": "6.0.0",
125125 "quickcheck": {
126126 "git": "https://github.com/purescm/purescript-core.git",
127− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
127+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
128128 "subdir": "quickcheck"
129129 },
130130 "random": {
131131 "git": "https://github.com/purescm/purescript-core.git",
132− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
132+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
133133 "subdir": "random"
134134 },
135135 "record": {
136136 "git": "https://github.com/purescm/purescript-core.git",
137− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
137+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
138138 "subdir": "record"
139139 },
140140 "refs": {
141141 "git": "https://github.com/purescm/purescript-core.git",
142− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
142+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
143143 "subdir": "refs"
144144 },
145145 "safe-coerce": "2.0.0",
146146 "st": {
147147 "git": "https://github.com/purescm/purescript-core.git",
148− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
148+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
149149 "subdir": "st"
150150 },
151151 "strings": {
152152 "git": "https://github.com/purescm/purescript-core.git",
153− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
153+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
154154 "subdir": "strings"
155155 },
156156 "semirings": "7.0.0",
@@ -161,12 +161,12 @@
161161 "typelevel-prelude": "7.0.0",
162162 "unfoldable": {
163163 "git": "https://github.com/purescm/purescript-core.git",
164− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
164+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
165165 "subdir": "unfoldable"
166166 },
167167 "unsafe-coerce": {
168168 "git": "https://github.com/purescm/purescript-core.git",
169− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
169+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
170170 "subdir": "unsafe-coerce",
171171 "dependencies": []
172172 },
package.json+1−1
@@ -1,6 +1,6 @@
11{
22 "name": "purescm",
3− "version": "1.11.0",
3+ "version": "1.12.0",
44 "main": "index.js",
55 "type": "module",
66 "files": [
spago.yaml+1−1
@@ -1,7 +1,7 @@
11package:
22 name: purescm
33 publish:
4− version: 1.11.0
4+ version: 1.13.0
55 license: Apache-2.0
66 location:
77 githubOwner: purescm
test-runtime.ss+4−1
@@ -1,9 +1,12 @@
11(import (chezscheme)
22 (only (purescm finalizers) run-finalizers)
33 (only (purescm stack-trace) print-stack-trace)
4− (only (purescm test pstring-test) main))
4+ (only (purescm test pstring-test) main)
5+ (rename (purescm test bytevector-test) (main bytevector-main)))
56(collect-request-handler (lambda () (collect) (run-finalizers)))
67(base-exception-handler (lambda (e) (print-stack-trace e) (exit -1)))
78(display "Testing pstring\n")
89(main)
10+(display "\nTesting bytevector\n")
11+(bytevector-main)
912(display "All good!\n")
test-snapshots/spago.lock+74−74
@@ -121,66 +121,66 @@
121121 "content": {
122122 "arrays": {
123123 "git": "https://github.com/purescm/purescript-core.git",
124− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
124+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
125125 "subdir": "arrays"
126126 },
127127 "assert": {
128128 "git": "https://github.com/purescm/purescript-core.git",
129− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
129+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
130130 "subdir": "assert"
131131 },
132132 "bifunctors": "6.0.0",
133133 "catenable-lists": "7.0.0",
134134 "console": {
135135 "git": "https://github.com/purescm/purescript-core.git",
136− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
136+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
137137 "subdir": "console"
138138 },
139139 "const": "6.0.0",
140140 "contravariant": "6.0.0",
141141 "control": {
142142 "git": "https://github.com/purescm/purescript-core.git",
143− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
143+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
144144 "subdir": "control"
145145 },
146146 "datetime": {
147147 "git": "https://github.com/purescm/purescript-core.git",
148− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
148+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
149149 "subdir": "datetime"
150150 },
151151 "distributive": "6.0.0",
152152 "effect": {
153153 "git": "https://github.com/purescm/purescript-core.git",
154− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
154+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
155155 "subdir": "effect"
156156 },
157157 "either": "6.1.0",
158158 "enums": {
159159 "git": "https://github.com/purescm/purescript-core.git",
160− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
160+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
161161 "subdir": "enums"
162162 },
163163 "exceptions": {
164164 "git": "https://github.com/purescm/purescript-core.git",
165− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
165+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
166166 "subdir": "exceptions"
167167 },
168168 "exists": "6.0.0",
169169 "filterable": "5.0.0",
170170 "foldable-traversable": {
171171 "git": "https://github.com/purescm/purescript-core.git",
172− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
172+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
173173 "subdir": "foldable-traversable"
174174 },
175175 "foreign-object": {
176176 "git": "https://github.com/purescm/purescript-core.git",
177− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
177+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
178178 "subdir": "foreign-object"
179179 },
180180 "free": "7.1.0",
181181 "functions": {
182182 "git": "https://github.com/purescm/purescript-core.git",
183− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
183+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
184184 "subdir": "functions",
185185 "dependencies": [
186186 "prelude"
@@ -191,18 +191,18 @@
191191 "identity": "6.0.0",
192192 "integers": {
193193 "git": "https://github.com/purescm/purescript-core.git",
194− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
194+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
195195 "subdir": "integers"
196196 },
197197 "invariant": "6.0.0",
198198 "json": {
199199 "git": "https://github.com/purescm/purescript-core.git",
200− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
200+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
201201 "subdir": "json"
202202 },
203203 "lazy": {
204204 "git": "https://github.com/purescm/purescript-core.git",
205− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
205+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
206206 "subdir": "lazy"
207207 },
208208 "lcg": "4.0.0",
@@ -213,14 +213,14 @@
213213 "maybe": "6.0.0",
214214 "minibench": {
215215 "git": "https://github.com/purescm/purescript-core.git",
216− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
216+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
217217 "subdir": "minibench"
218218 },
219219 "newtype": "5.0.0",
220220 "nonempty": "7.0.0",
221221 "numbers": {
222222 "git": "https://github.com/purescm/purescript-core.git",
223− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
223+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
224224 "subdir": "numbers"
225225 },
226226 "ordered-collections": "3.1.1",
@@ -228,46 +228,46 @@
228228 "parallel": "7.0.0",
229229 "partial": {
230230 "git": "https://github.com/purescm/purescript-core.git",
231− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
231+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
232232 "subdir": "partial",
233233 "dependencies": []
234234 },
235235 "prelude": {
236236 "git": "https://github.com/purescm/purescript-core.git",
237− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
237+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
238238 "subdir": "prelude"
239239 },
240240 "profunctor": "6.0.0",
241241 "quickcheck": {
242242 "git": "https://github.com/purescm/purescript-core.git",
243− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
243+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
244244 "subdir": "quickcheck"
245245 },
246246 "random": {
247247 "git": "https://github.com/purescm/purescript-core.git",
248− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
248+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
249249 "subdir": "random"
250250 },
251251 "record": {
252252 "git": "https://github.com/purescm/purescript-core.git",
253− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
253+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
254254 "subdir": "record"
255255 },
256256 "refs": {
257257 "git": "https://github.com/purescm/purescript-core.git",
258− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
258+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
259259 "subdir": "refs"
260260 },
261261 "safe-coerce": "2.0.0",
262262 "semirings": "7.0.0",
263263 "st": {
264264 "git": "https://github.com/purescm/purescript-core.git",
265− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
265+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
266266 "subdir": "st"
267267 },
268268 "strings": {
269269 "git": "https://github.com/purescm/purescript-core.git",
270− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
270+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
271271 "subdir": "strings"
272272 },
273273 "tailrec": "6.1.0",
@@ -277,12 +277,12 @@
277277 "typelevel-prelude": "7.0.0",
278278 "unfoldable": {
279279 "git": "https://github.com/purescm/purescript-core.git",
280− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
280+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
281281 "subdir": "unfoldable"
282282 },
283283 "unsafe-coerce": {
284284 "git": "https://github.com/purescm/purescript-core.git",
285− "ref": "1982feebeb96103c9e8caaf6a646498445e61cb5",
285+ "ref": "b5474536977275bda9b1771e06e5f697e0a846d9",
286286 "subdir": "unsafe-coerce",
287287 "dependencies": []
288288 },
@@ -295,7 +295,7 @@
295295 "arrays": {
296296 "type": "git",
297297 "url": "https://github.com/purescm/purescript-core.git",
298− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
298+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
299299 "subdir": "arrays",
300300 "dependencies": [
301301 "bifunctors",
@@ -317,7 +317,7 @@
317317 "assert": {
318318 "type": "git",
319319 "url": "https://github.com/purescm/purescript-core.git",
320− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
320+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
321321 "subdir": "assert",
322322 "dependencies": [
323323 "console",
@@ -328,7 +328,7 @@
328328 "bifunctors": {
329329 "type": "registry",
330330 "version": "6.0.0",
331− "integrity": "sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw=",
331+ "integrity": "sha256-tXhmlMiyVy6mbUreVZQt/2EGEsPr0T1PjJi+YCG5J7E=",
332332 "dependencies": [
333333 "const",
334334 "either",
@@ -340,7 +340,7 @@
340340 "catenable-lists": {
341341 "type": "registry",
342342 "version": "7.0.0",
343− "integrity": "sha256-76vYENhwF4BWTBsjeLuErCH2jqVT4M3R1HX+4RwSftA=",
343+ "integrity": "sha256-7+i/MHBLIRh604iCNT4ENWRWE/wuHIotER4kpdX9Ve0=",
344344 "dependencies": [
345345 "control",
346346 "foldable-traversable",
@@ -354,7 +354,7 @@
354354 "console": {
355355 "type": "git",
356356 "url": "https://github.com/purescm/purescript-core.git",
357− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
357+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
358358 "subdir": "console",
359359 "dependencies": [
360360 "effect",
@@ -364,7 +364,7 @@
364364 "const": {
365365 "type": "registry",
366366 "version": "6.0.0",
367− "integrity": "sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc=",
367+ "integrity": "sha256-S+m0lQsxnji0z1XRUmkn+3RFuWJ5CXWuIr1u3i8Bfoc=",
368368 "dependencies": [
369369 "invariant",
370370 "newtype",
@@ -374,7 +374,7 @@
374374 "contravariant": {
375375 "type": "registry",
376376 "version": "6.0.0",
377− "integrity": "sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c=",
377+ "integrity": "sha256-nuckEWqL80NaPmR/l9AUyrfycNh18XcvlZV9PAamwqc=",
378378 "dependencies": [
379379 "const",
380380 "either",
@@ -386,7 +386,7 @@
386386 "control": {
387387 "type": "git",
388388 "url": "https://github.com/purescm/purescript-core.git",
389− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
389+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
390390 "subdir": "control",
391391 "dependencies": [
392392 "newtype",
@@ -396,7 +396,7 @@
396396 "distributive": {
397397 "type": "registry",
398398 "version": "6.0.0",
399− "integrity": "sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ=",
399+ "integrity": "sha256-netyJK4B32PDYHD0tF2AenKgo3urzbI770ycM0pArAo=",
400400 "dependencies": [
401401 "identity",
402402 "newtype",
@@ -408,7 +408,7 @@
408408 "effect": {
409409 "type": "git",
410410 "url": "https://github.com/purescm/purescript-core.git",
411− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
411+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
412412 "subdir": "effect",
413413 "dependencies": [
414414 "prelude"
@@ -417,7 +417,7 @@
417417 "either": {
418418 "type": "registry",
419419 "version": "6.1.0",
420− "integrity": "sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY=",
420+ "integrity": "sha256-tBHx3PgtH4GZOApZCDkcM7szRTYJinrUrVGWazQCUUg=",
421421 "dependencies": [
422422 "control",
423423 "invariant",
@@ -428,7 +428,7 @@
428428 "enums": {
429429 "type": "git",
430430 "url": "https://github.com/purescm/purescript-core.git",
431− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
431+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
432432 "subdir": "enums",
433433 "dependencies": [
434434 "control",
@@ -446,7 +446,7 @@
446446 "exceptions": {
447447 "type": "git",
448448 "url": "https://github.com/purescm/purescript-core.git",
449− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
449+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
450450 "subdir": "exceptions",
451451 "dependencies": [
452452 "effect",
@@ -458,7 +458,7 @@
458458 "exists": {
459459 "type": "registry",
460460 "version": "6.0.0",
461− "integrity": "sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8=",
461+ "integrity": "sha256-vtLbrWNaI+pzx/2fw2AQnCovoLtcosClIhjO26QKkh8=",
462462 "dependencies": [
463463 "unsafe-coerce"
464464 ]
@@ -466,7 +466,7 @@
466466 "filterable": {
467467 "type": "registry",
468468 "version": "5.0.0",
469− "integrity": "sha256-cCojJHRnTmpY1j1kegI4CFwghdQ2Fm/8dzM8IlC+lng=",
469+ "integrity": "sha256-be7ci1Bzwud2waqoCtNGsTBZbt7fi+gCLvGddQQRJ3A=",
470470 "dependencies": [
471471 "arrays",
472472 "either",
@@ -479,7 +479,7 @@
479479 "foldable-traversable": {
480480 "type": "git",
481481 "url": "https://github.com/purescm/purescript-core.git",
482− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
482+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
483483 "subdir": "foldable-traversable",
484484 "dependencies": [
485485 "bifunctors",
@@ -498,7 +498,7 @@
498498 "free": {
499499 "type": "registry",
500500 "version": "7.1.0",
501− "integrity": "sha256-JAumgEsGSzJCNLD8AaFvuX7CpqS5yruCngi6yI7+V5k=",
501+ "integrity": "sha256-tUBInfUpRQEw4u94GWcYW7EYdmSdDHSRn88a+C0eltU=",
502502 "dependencies": [
503503 "catenable-lists",
504504 "control",
@@ -519,7 +519,7 @@
519519 "functions": {
520520 "type": "git",
521521 "url": "https://github.com/purescm/purescript-core.git",
522− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
522+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
523523 "subdir": "functions",
524524 "dependencies": [
525525 "prelude"
@@ -528,7 +528,7 @@
528528 "functors": {
529529 "type": "registry",
530530 "version": "5.0.0",
531− "integrity": "sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU=",
531+ "integrity": "sha256-W1o/4wcp6S3chodYL8uixlXK2mfr1L+SzM1R+whqUco=",
532532 "dependencies": [
533533 "bifunctors",
534534 "const",
@@ -548,7 +548,7 @@
548548 "gen": {
549549 "type": "registry",
550550 "version": "4.0.0",
551− "integrity": "sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI=",
551+ "integrity": "sha256-kyOateeOtQa07vfTMYeSuCKdelgKE1R65fwKkZ10wsY=",
552552 "dependencies": [
553553 "either",
554554 "foldable-traversable",
@@ -565,7 +565,7 @@
565565 "identity": {
566566 "type": "registry",
567567 "version": "6.0.0",
568− "integrity": "sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY=",
568+ "integrity": "sha256-RY/iXPpxpqvKHYfJeFVNI1J06kohB9rbtWYuha8t0LE=",
569569 "dependencies": [
570570 "control",
571571 "invariant",
@@ -576,7 +576,7 @@
576576 "integers": {
577577 "type": "git",
578578 "url": "https://github.com/purescm/purescript-core.git",
579− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
579+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
580580 "subdir": "integers",
581581 "dependencies": [
582582 "maybe",
@@ -587,7 +587,7 @@
587587 "invariant": {
588588 "type": "registry",
589589 "version": "6.0.0",
590− "integrity": "sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo=",
590+ "integrity": "sha256-HyoT1I5qIHRq8RSZji6zZDvqnpVjLw748utrKwZtqsw=",
591591 "dependencies": [
592592 "control",
593593 "prelude"
@@ -596,7 +596,7 @@
596596 "lazy": {
597597 "type": "git",
598598 "url": "https://github.com/purescm/purescript-core.git",
599− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
599+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
600600 "subdir": "lazy",
601601 "dependencies": [
602602 "control",
@@ -627,7 +627,7 @@
627627 "maybe": {
628628 "type": "registry",
629629 "version": "6.0.0",
630− "integrity": "sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q=",
630+ "integrity": "sha256-8X6XEgtZ5lqfkEuc1hWOofnL6mwhk8gSJTxwvbR/SbY=",
631631 "dependencies": [
632632 "control",
633633 "invariant",
@@ -638,7 +638,7 @@
638638 "minibench": {
639639 "type": "git",
640640 "url": "https://github.com/purescm/purescript-core.git",
641− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
641+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
642642 "subdir": "minibench",
643643 "dependencies": [
644644 "console",
@@ -652,7 +652,7 @@
652652 "newtype": {
653653 "type": "registry",
654654 "version": "5.0.0",
655− "integrity": "sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw=",
655+ "integrity": "sha256-dt6w0cty4OS+Pjt9fsh3iU6ottqSU83mdAZkaEEvo6c=",
656656 "dependencies": [
657657 "prelude",
658658 "safe-coerce"
@@ -661,7 +661,7 @@
661661 "nonempty": {
662662 "type": "registry",
663663 "version": "7.0.0",
664− "integrity": "sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs=",
664+ "integrity": "sha256-Ctkq8/+KiGqCE53Y/LvibA/coy7ev9HtRZU+GYS7yfQ=",
665665 "dependencies": [
666666 "control",
667667 "foldable-traversable",
@@ -674,7 +674,7 @@
674674 "numbers": {
675675 "type": "git",
676676 "url": "https://github.com/purescm/purescript-core.git",
677− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
677+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
678678 "subdir": "numbers",
679679 "dependencies": [
680680 "functions",
@@ -685,7 +685,7 @@
685685 "ordered-collections": {
686686 "type": "registry",
687687 "version": "3.1.1",
688− "integrity": "sha256-boSYHmlz4aSbwsNN4VxiwCStc0t+y1F7BXmBS+1JNtI=",
688+ "integrity": "sha256-gr9Eqg4/XcJylARhTyxb0w9yqzS3tgloqyg57Q6SHug=",
689689 "dependencies": [
690690 "arrays",
691691 "foldable-traversable",
@@ -703,7 +703,7 @@
703703 "orders": {
704704 "type": "registry",
705705 "version": "6.0.0",
706− "integrity": "sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink=",
706+ "integrity": "sha256-nSMxZK7wxyDULkjZqvMyB71mVo6b0AyLLHosDVbv1XM=",
707707 "dependencies": [
708708 "newtype",
709709 "prelude"
@@ -712,7 +712,7 @@
712712 "parallel": {
713713 "type": "registry",
714714 "version": "7.0.0",
715− "integrity": "sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o=",
715+ "integrity": "sha256-bAGpVhrFz2IyHkA4MR7+tE/19FZ7dzYBdYPgK5svkqw=",
716716 "dependencies": [
717717 "control",
718718 "effect",
@@ -730,21 +730,21 @@
730730 "partial": {
731731 "type": "git",
732732 "url": "https://github.com/purescm/purescript-core.git",
733− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
733+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
734734 "subdir": "partial",
735735 "dependencies": []
736736 },
737737 "prelude": {
738738 "type": "git",
739739 "url": "https://github.com/purescm/purescript-core.git",
740− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
740+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
741741 "subdir": "prelude",
742742 "dependencies": []
743743 },
744744 "profunctor": {
745745 "type": "registry",
746746 "version": "6.0.0",
747− "integrity": "sha256-99NzxFgTr4CGlCSRYG1kShL+JhYbihhHtbOk1/0R5zI=",
747+ "integrity": "sha256-f1L0opNYQcjRpbmjgkSA2AlbaiSEfsu60mW3j/hcs2U=",
748748 "dependencies": [
749749 "control",
750750 "distributive",
@@ -759,7 +759,7 @@
759759 "record": {
760760 "type": "git",
761761 "url": "https://github.com/purescm/purescript-core.git",
762− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
762+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
763763 "subdir": "record",
764764 "dependencies": [
765765 "functions",
@@ -770,7 +770,7 @@
770770 "refs": {
771771 "type": "git",
772772 "url": "https://github.com/purescm/purescript-core.git",
773− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
773+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
774774 "subdir": "refs",
775775 "dependencies": [
776776 "effect",
@@ -780,7 +780,7 @@
780780 "safe-coerce": {
781781 "type": "registry",
782782 "version": "2.0.0",
783− "integrity": "sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=",
783+ "integrity": "sha256-EJrxtKt5xC7TYjBZrSBO/J7Aw3DmtilYjt4olpAXWVc=",
784784 "dependencies": [
785785 "unsafe-coerce"
786786 ]
@@ -788,7 +788,7 @@
788788 "semirings": {
789789 "type": "registry",
790790 "version": "7.0.0",
791− "integrity": "sha256-2qGNMxVYns7RJxZd1uGtJbGTeVl/6Ozsz9OM5gRM61A=",
791+ "integrity": "sha256-wjcUvWi+KK4pktI1PAJKjPFTBPeSeIZniTi30VlYtSs=",
792792 "dependencies": [
793793 "foldable-traversable",
794794 "lists",
@@ -799,7 +799,7 @@
799799 "st": {
800800 "type": "git",
801801 "url": "https://github.com/purescm/purescript-core.git",
802− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
802+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
803803 "subdir": "st",
804804 "dependencies": [
805805 "effect",
@@ -812,7 +812,7 @@
812812 "strings": {
813813 "type": "git",
814814 "url": "https://github.com/purescm/purescript-core.git",
815− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
815+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
816816 "subdir": "strings",
817817 "dependencies": [
818818 "arrays",
@@ -836,7 +836,7 @@
836836 "tailrec": {
837837 "type": "registry",
838838 "version": "6.1.0",
839− "integrity": "sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk=",
839+ "integrity": "sha256-xrorCfP0xV1wubs27idQCHQqdvSUuqmmL/am7Ji1wVU=",
840840 "dependencies": [
841841 "bifunctors",
842842 "effect",
@@ -851,7 +851,7 @@
851851 "transformers": {
852852 "type": "registry",
853853 "version": "6.0.0",
854− "integrity": "sha256-Pzw40HjthX77tdPAYzjx43LK3X5Bb7ZspYAp27wksFA=",
854+ "integrity": "sha256-Nl3yXAIeeTzP6MyrkazkK7pbgeVqUm+ynLv7U5cpJYQ=",
855855 "dependencies": [
856856 "control",
857857 "distributive",
@@ -872,7 +872,7 @@
872872 "tuples": {
873873 "type": "registry",
874874 "version": "7.0.0",
875− "integrity": "sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M=",
875+ "integrity": "sha256-BKy7EfK8S1KeTCwyWqyW1wwcpSAQuh3IsczSVgS6fzY=",
876876 "dependencies": [
877877 "control",
878878 "invariant",
@@ -882,13 +882,13 @@
882882 "type-equality": {
883883 "type": "registry",
884884 "version": "4.0.1",
885− "integrity": "sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=",
885+ "integrity": "sha256-BBqYOSnAKmayRvR5mtZoCf4SlYs2ipatD/+5nQx73aw=",
886886 "dependencies": []
887887 },
888888 "unfoldable": {
889889 "type": "git",
890890 "url": "https://github.com/purescm/purescript-core.git",
891− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
891+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
892892 "subdir": "unfoldable",
893893 "dependencies": [
894894 "foldable-traversable",
@@ -901,14 +901,14 @@
901901 "unsafe-coerce": {
902902 "type": "git",
903903 "url": "https://github.com/purescm/purescript-core.git",
904− "rev": "1982feebeb96103c9e8caaf6a646498445e61cb5",
904+ "rev": "b5474536977275bda9b1771e06e5f697e0a846d9",
905905 "subdir": "unsafe-coerce",
906906 "dependencies": []
907907 },
908908 "validation": {
909909 "type": "registry",
910910 "version": "6.0.0",
911− "integrity": "sha256-kfFailaIW4spGxbRk4261z/RGT0Sb7Dx5f3qihy0MTw=",
911+ "integrity": "sha256-wavSVs3zeQmO3iXJJlhyQuDOh6w3ngO3gwWqcwekG/U=",
912912 "dependencies": [
913913 "bifunctors",
914914 "control",