diff --git a/lens/private/dict.rkt b/lens/private/dict.rkt index fbf15c7..b6c1f06 100644 --- a/lens/private/dict.rkt +++ b/lens/private/dict.rkt @@ -6,7 +6,7 @@ (-> any/c (lens/c functional-dict? any/c))] )) -(require racket/dict fancy-app "base/main.rkt") +(require lens/private/util/functional-dict racket/dict fancy-app "base/main.rkt") (module+ test (require rackunit)) @@ -14,9 +14,6 @@ (make-lens (dict-ref _ key) (dict-set _ key _))) -(define (functional-dict? v) - (and (dict? v) (dict-can-functional-set? v))) - (module+ test (check-equal? (lens-transform/list '((a . 1) (b . 2) (c . 3)) (dict-ref-lens 'a) (* 100 _)) '((a . 100) (b . 2) (c . 3)))) diff --git a/lens/private/util/functional-dict.rkt b/lens/private/util/functional-dict.rkt new file mode 100644 index 0000000..7a1448a --- /dev/null +++ b/lens/private/util/functional-dict.rkt @@ -0,0 +1,15 @@ +#lang sweet-exp racket/base + +provide functional-dict? + +require racket/dict +module+ test + require rackunit + +(define (functional-dict? v) + (and (dict? v) (dict-can-functional-set? v))) + +module+ test + (check-true (functional-dict? (hash 'a 1 'b 2))) + (check-true (functional-dict? '((a . 1) (b . 2)))) + (check-false (functional-dict? (make-hash '((a . 1) (b . 2))))) diff --git a/unstable/lens/dict-nested.rkt b/unstable/lens/dict-nested.rkt new file mode 100644 index 0000000..c54b362 --- /dev/null +++ b/unstable/lens/dict-nested.rkt @@ -0,0 +1,24 @@ +#lang sweet-exp racket/base + +require racket/contract/base +provide + contract-out + dict-ref-nested-lens (->* [] #:rest (listof any/c) (lens/c functional-dict? any/c)) + +require lens/private/base/main + lens/private/compound/thrush + lens/private/dict + lens/private/util/functional-dict +module+ test + require rackunit fancy-app + +(define (dict-ref-nested-lens . ks) + (apply lens-thrush (map dict-ref-lens ks))) + +module+ test + (define a-x (dict-ref-nested-lens 'a 'x)) + (let-lens [val ctxt] a-x '([a . ([x . 1] [y . 2])] '[b . ([z . 3])]) + (check-equal? val 1) + (check-equal? (ctxt 100) '([a . ([x . 100] [y . 2])] '[b . ([z . 3])]))) + (check-equal? (lens-transform/list '([a . ([x . 1] [y . 2])] '[b . ([z . 3])]) a-x (* 10 _)) + '([a . ([x . 10] [y . 2])] '[b . ([z . 3])])) diff --git a/unstable/lens/dict-nested.scrbl b/unstable/lens/dict-nested.scrbl new file mode 100644 index 0000000..9bcad13 --- /dev/null +++ b/unstable/lens/dict-nested.scrbl @@ -0,0 +1,15 @@ +#lang scribble/manual + +@(require lens/private/doc-util/main) + +@title{Lenses for nested dictionaries} + +@defmodule[unstable/lens/dict-nested] + +@defproc[(dict-ref-nested-lens [k any/c] ...) (lens/c functional-dict? any/c)]{ +Similar to @racket[hash-ref-nested-lens], but for dicts. +@lens-unstable-examples[ + (define a-x (dict-ref-nested-lens 'a 'x)) + (lens-view a-x '([a . ([x . 1] [y . 2])] '[b . ([z . 3])])) + (lens-set a-x '([a . ([x . 1] [y . 2])] '[b . ([z . 3])]) 100) +]} diff --git a/unstable/lens/main.rkt b/unstable/lens/main.rkt index a390a8b..faa51dd 100644 --- a/unstable/lens/main.rkt +++ b/unstable/lens/main.rkt @@ -1,5 +1,6 @@ #lang reprovide "arrow.rkt" +"dict-nested.rkt" "if.rkt" "isomorphism.rkt" "mapper.rkt" diff --git a/unstable/lens/main.scrbl b/unstable/lens/main.scrbl index 32cada2..dd30ab7 100644 --- a/unstable/lens/main.scrbl +++ b/unstable/lens/main.scrbl @@ -13,6 +13,7 @@ this library being backwards-compatible. @(include-sections "arrow.scrbl" + "dict-nested.scrbl" "if.scrbl" "isomorphism.scrbl" "mapper.scrbl"