diff --git a/unstable/lens/arrow.rkt b/unstable/lens/arrow.rkt new file mode 100644 index 0000000..ae6373c --- /dev/null +++ b/unstable/lens/arrow.rkt @@ -0,0 +1,42 @@ +#lang racket/base + +(provide lens-view~> + lens-set~> + lens-transform~> + lens-view/thrush + lens-set/thrush + lens-transform/thrush + ) + +(require lens/base/main) +(module+ test + (require rackunit racket/list fancy-app)) + +(define (lens-view~> target . lenses) + (for/fold ([target target]) ([lens (in-list lenses)]) + (lens-view lens target))) + +(define (lens-set~> target #:-> new-val . lenses) + (lens-set (apply lens-thrush lenses) target new-val)) + +(define (lens-transform~> target #:-> transformer . lenses) + (lens-transform (apply lens-thrush lenses) target transformer)) + +(define lens-view/thrush lens-view~>) +(define lens-set/thrush lens-set~>) +(define lens-transform/thrush lens-transform~>) + +(module+ test + (define (set-first l v) + (list* v (rest l))) + (define (set-second l v) + (list* (first l) v (rest (rest l)))) + (define first-lens (make-lens first set-first)) + (define second-lens (make-lens second set-second)) + (check-equal? (lens-view~> '((1 2) 3) first-lens second-lens) + 2) + (check-equal? (lens-set~> '((1 2) 3) first-lens second-lens #:-> 'two) + '((1 two) 3)) + (check-equal? (lens-transform~> '((1 2) 3) first-lens second-lens #:-> (* 100 _)) + '((1 200) 3)) + ) diff --git a/unstable/lens/arrow.scrbl b/unstable/lens/arrow.scrbl new file mode 100644 index 0000000..4134ae8 --- /dev/null +++ b/unstable/lens/arrow.scrbl @@ -0,0 +1,52 @@ +#lang scribble/manual + +@(require lens/doc-util/main) + +@title{lens-view/thrush, lens-set/thrush, and lens-transform/thrush} + +@defmodule[unstable/lens/arrow] + +@deftogether[[@defproc[(lens-view/thrush [target any/c] [lens lens?] ...) any/c] + @defproc[(lens-view~> [target any/c] [lens lens?] ...) any/c]]]{ +Like @racket[lens-view], except that it can take multiple lenses, +which are combined into a nested lens. The argument order is +switched, so that the @racket[target] comes first and the +@racket[lens] arguments come after it. +@racket[(lens-view/thrush target lens ...)] produces the same value as +@racket[(lens-view (lens-thrush lens ...) target)], but can be more +efficient. +The function @racket[lens-view~>] is provided as a shorter version. +@lenses-examples[ + (lens-view/thrush '(a b ((c d) e f) g) third-lens first-lens second-lens) + (lens-view~> '(a b ((c d) e f) g) third-lens first-lens second-lens) +]} + +@deftogether[[@defproc[(lens-set/thrush [target any/c] [lens lens?] ... [#:-> new-view any/c]) any/c] + @defproc[(lens-set~> [target any/c] [lens lens?] ... [#:-> new-view any/c]) any/c]]]{ +Like @racket[lens-set], except that it can take multiple lenses, +which again are combined into a nested lens. +@racket[(lens-set/thrush target lens ... #:-> new-view)] is equivalent +to @racket[(lens-set (lens-thrush lens ...) target new-view)], and +@racket[lens-set~>] is the shorter version. +@lenses-examples[ + (lens-set/thrush '(a b ((c d) e f) g) third-lens first-lens second-lens #:-> "sea") + (lens-set~> '(a b ((c d) e f) g) third-lens first-lens second-lens #:-> "sea") +]} + +@deftogether[[@defproc[(lens-transform/thrush [target any/c] [lens lens?] ... + [#:-> transformer (-> any/c any/c)]) + any/c] + @defproc[(lens-transform~> [target any/c] [lens lens?] ... + [#:-> transformer (-> any/c any/c)]) + any/c]]]{ +Like @racket[lens-transform], except that it can take multiple lenses, +just like @racket[lens-set/thrush]. +@racket[(lens-transform/thrush target lens ... #:-> transformer)] is +equivalent to +@racket[(lens-transform (lens-thrush lens ...) target transformer)], +and @racket[lens-transform~>] is the shorter verison. +@lenses-examples[ + (lens-transform/thrush '(a b ((c d) e f) g) third-lens first-lens second-lens #:-> symbol->string) + (lens-transform~> '(a b ((c d) e f) g) third-lens first-lens second-lens #:-> symbol->string) +]} + diff --git a/unstable/lens/main.rkt b/unstable/lens/main.rkt index bdc0389..2aba118 100644 --- a/unstable/lens/main.rkt +++ b/unstable/lens/main.rkt @@ -7,6 +7,7 @@ "view-set.rkt" "sublist.rkt" "struct.rkt" + "arrow.rkt" ) (provide (all-from-out "syntax.rkt" @@ -16,4 +17,5 @@ "view-set.rkt" "sublist.rkt" "struct.rkt" + "arrow.rkt" )) diff --git a/unstable/lens/main.scrbl b/unstable/lens/main.scrbl index 8ee9a58..fbc829a 100644 --- a/unstable/lens/main.scrbl +++ b/unstable/lens/main.scrbl @@ -16,3 +16,4 @@ this library being backwards-compatible. @include-section["syntax.scrbl"] @include-section["sublist.scrbl"] @include-section["struct.scrbl"] +@include-section["arrow.scrbl"]