;;; CHICKEN Transducers - Transducers for working with foldable data types. ;;; ;;; Copyright (c) 2022 Jeremy Steward ;;; ;;; Permission is hereby granted, free of charge, to any person obtaining a copy ;;; of this software and associated documentation files (the "Software"), to deal ;;; in the Software without restriction, including without limitation the rights ;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ;;; copies of the Software, and to permit persons to whom the Software is ;;; furnished to do so, subject to the following conditions: ;;; ;;; The above copyright notice and this permission notice shall be included in all ;;; copies or substantial portions of the Software. ;;; ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ;;; SOFTWARE. (module (transducers ports) () (import (scheme)) (import (chicken base) (chicken module) (check-errors) (transducers base)) (export reader-fold collect-writer chain-reader interleave-reader zip-reader) ;; A reducer that aggregates the transduction into a new list in the order of ;; the items reduced. (define (collect-writer writer) (case-lambda (() (void)) ((result) result) ((result item) (writer item)))) ;; Transducer-aware folding operation over ports given a reader procedure. ;; ;; This procedure takes in a reducer `f`, a `sentinel` value for that ;; reducer, and a reader `reader` to call `(f sentinel x)` on repeatedly, ;; taking the result of the reducer as the new sentinel value each time. (define (reader-fold f sentinel reader) (check-procedure 'reader-fold reader 'reader) (let loop ((collector sentinel) (x (reader))) (if (eof-object? x) collector (let ((result (f collector x))) (if (reduced? result) (unwrap result) (loop result (reader))))))) ;; A transducer that chains another reader onto the current transduction (define-chain-transducer chain-reader reader-fold) ;; A transducer that interleaves the contents of a list (define-interleave-transducer interleave-reader (lambda (reader) (reader)) (lambda (_ s) (eof-object? s)) (lambda (_ s) s) (lambda (reader _) (reader))) ;; A transducer that zips the contents of a list (define-zip-transducer zip-reader (lambda (reader) (reader)) (lambda (_ s) (eof-object? s)) (lambda (_ s) s) (lambda (reader _) (reader))) ;; End-of-module )