From 0f2512ec9f618a0bce7eea6b1e3e82cf00b6f53d Mon Sep 17 00:00:00 2001 From: AlexKnauth Date: Mon, 20 Jul 2015 13:48:07 -0400 Subject: [PATCH 1/4] add isomorphism lenses --- unstable/lens/isomorphism.rkt | 3 ++ unstable/lens/isomorphism/base.rkt | 64 ++++++++++++++++++++++++++++++ unstable/lens/isomorphism/data.rkt | 3 ++ 3 files changed, 70 insertions(+) create mode 100644 unstable/lens/isomorphism.rkt create mode 100644 unstable/lens/isomorphism/base.rkt create mode 100644 unstable/lens/isomorphism/data.rkt diff --git a/unstable/lens/isomorphism.rkt b/unstable/lens/isomorphism.rkt new file mode 100644 index 0000000..6d413a3 --- /dev/null +++ b/unstable/lens/isomorphism.rkt @@ -0,0 +1,3 @@ +#lang racket/base +(require "isomorphism/base.rkt" "isomorphism/data.rkt") +(provide (all-from-out "isomorphism/base.rkt" "isomorphism/data.rkt")) diff --git a/unstable/lens/isomorphism/base.rkt b/unstable/lens/isomorphism/base.rkt new file mode 100644 index 0000000..be8c779 --- /dev/null +++ b/unstable/lens/isomorphism/base.rkt @@ -0,0 +1,64 @@ +#lang racket/base + +(provide isomorphism-lens + isomorphism-lens? + isomorphism-lens-inverse + isomorphism-lenses + ) +(module+ data + (provide string->symbol-lens symbol->string-lens + number->string-lens string->number-lens + list->vector-lens vector->list-lens + list->string-lens string->list-lens + )) + +(require racket/match + lens/base/main + ) +(module+ test + (require rackunit (submod ".." data))) + +(struct isomorphism-lens (f inv) #:transparent + #:methods gen:lens + [(define (lens-view lens tgt) + ((isomorphism-lens-f lens) tgt)) + (define (lens-set lens tgt v) + ((isomorphism-lens-inv lens) v))]) + +(define (isomorphism-lens-inverse lens) + (match lens + [(isomorphism-lens f inv) + (isomorphism-lens inv f)])) + +(define (isomorphism-lenses f inv) + (values (isomorphism-lens f inv) + (isomorphism-lens inv f))) + +(module+ data + (define-values [string->symbol-lens symbol->string-lens] + (isomorphism-lenses string->symbol symbol->string)) + (define-values [number->string-lens string->number-lens] + (isomorphism-lenses number->string string->number)) + (define-values [list->vector-lens vector->list-lens] + (isomorphism-lenses list->vector vector->list)) + (define-values [list->string-lens string->list-lens] + (isomorphism-lenses list->string string->list)) + ) + +(module+ test + (test-case "string-symbol" + (check-equal? (lens-view string->symbol-lens "a") 'a) + (check-equal? (lens-set string->symbol-lens "a" 'b) "b") + (check-equal? (lens-view symbol->string-lens 'a) "a") + (check-equal? (lens-set symbol->string-lens 'a "b") 'b)) + (test-case "number-string" + (check-equal? (lens-view number->string-lens 5) "5") + (check-equal? (lens-set number->string-lens 5 "6") 6) + (check-equal? (lens-view string->number-lens "5") 5) + (check-equal? (lens-set string->number-lens "5" 6) "6")) + (test-case "inverses" + (check-equal? (isomorphism-lens-inverse string->symbol-lens) symbol->string-lens) + (check-equal? (isomorphism-lens-inverse symbol->string-lens) string->symbol-lens) + (check-equal? (isomorphism-lens-inverse number->string-lens) string->number-lens) + (check-equal? (isomorphism-lens-inverse string->number-lens) number->string-lens)) + ) diff --git a/unstable/lens/isomorphism/data.rkt b/unstable/lens/isomorphism/data.rkt new file mode 100644 index 0000000..e558621 --- /dev/null +++ b/unstable/lens/isomorphism/data.rkt @@ -0,0 +1,3 @@ +#lang racket/base +(require (submod "base.rkt" data)) +(provide (all-from-out (submod "base.rkt" data))) From 52d6d79f772217b71b694f93efaa6ebcf73d2c49 Mon Sep 17 00:00:00 2001 From: AlexKnauth Date: Mon, 20 Jul 2015 14:32:52 -0400 Subject: [PATCH 2/4] add docs and provide from unstable/lens --- unstable/lens/isomorphism.scrbl | 54 +++++++++++++++++++++++++++++++++ unstable/lens/main.rkt | 8 +++-- unstable/lens/main.scrbl | 1 + 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 unstable/lens/isomorphism.scrbl diff --git a/unstable/lens/isomorphism.scrbl b/unstable/lens/isomorphism.scrbl new file mode 100644 index 0000000..26c23bf --- /dev/null +++ b/unstable/lens/isomorphism.scrbl @@ -0,0 +1,54 @@ +#lang scribble/manual + +@(require lens/doc-util/main) + +@title{Isomorphisms} + +@defmodule[unstable/lens/isomorphism] + +@defproc[(isomorphism-lens [f (a/c . -> . b/c)] [inv (b/c . -> . a/c)]) lens?]{ +Creates a lens for an isomorphism. The @racket[f] argument should be a function +with an inverse, and the @racket[inv] argument should be its inverse. +The @racket[f] function converts targets to views, and the @racket[inv] function +converts views to targets. + +So for instance a @racket[symbol->string-lens] could be defined with: +@racketblock[ + (define symbol->string-lens + (isomorphism-lens symbol->string string->symbol)) +] +@lenses-unstable-examples[ + (lens-view symbol->string-lens 'something) + (lens-transform symbol->string-lens 'something (λ (s) (string-append "make-" s))) +]} + +@defproc[(isomorphism-lens? [v any/c]) boolean?]{ +A predicate that returns true when @racket[v] is a lens constructed with +@racket[isomorphism-lens], @racket[isomorphism-lens-inverse], or +@racket[isomorphism-lenses], and returns false otherwise. +All isomorphism lenses are also lenses according to @racket[lens?]. +} + +@defproc[(isomorphism-lens-inverse [iso-lens isomorphism-lens?]) isomorphism-lens?]{ +Returns the inverse of @racket[iso-lens]. +} + +@defproc[(isomorphism-lenses [f (a/c . -> . b/c)] [inv (b/c . -> . a/c)]) + (values isomorphism-lens? isomorphism-lens?)]{ +Returns two values. The first value is the result of +@racket[(isomorphism-lens f inv)], and the second value is the inverse of that +lens. + +The lenses @racket[symbol->string-lens] and @racket[string->symbol-lens], for +example, are defined like this: +@racketblock[ + (define-values [string->symbol-lens symbol->string-lens] + (isomorphism-lenses string->symbol symbol->string)) +]} + +@deflenses[[string->symbol-lens symbol->string-lens + number->string-lens string->number-lens + list->vector-lens vector->list-lens + list->string-lens string->list-lens]]{ +Isomorphim lenses for @racket[string->symbol], @racket[number->string], and so on. +} diff --git a/unstable/lens/main.rkt b/unstable/lens/main.rkt index a4ebac0..c02a2bc 100644 --- a/unstable/lens/main.rkt +++ b/unstable/lens/main.rkt @@ -3,9 +3,13 @@ (require "syntax.rkt" "view-set.rkt" "sublist.rkt" - "arrow.rkt") + "arrow.rkt" + "isomorphism.rkt" + ) (provide (all-from-out "syntax.rkt" "view-set.rkt" "sublist.rkt" - "arrow.rkt")) + "arrow.rkt" + "isomorphism.rkt" + )) diff --git a/unstable/lens/main.scrbl b/unstable/lens/main.scrbl index c535fc3..26e8f30 100644 --- a/unstable/lens/main.scrbl +++ b/unstable/lens/main.scrbl @@ -13,3 +13,4 @@ this library being backwards-compatible. @include-section["syntax.scrbl"] @include-section["sublist.scrbl"] @include-section["arrow.scrbl"] +@include-section["isomorphism.scrbl"] From 3777672173c489224ca5f9739ce4c78457862f31 Mon Sep 17 00:00:00 2001 From: AlexKnauth Date: Sun, 16 Aug 2015 19:34:16 -0500 Subject: [PATCH 3/4] add hash->list-lens and list->hash-lens --- unstable/lens/isomorphism.scrbl | 3 ++- unstable/lens/isomorphism/base.rkt | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/unstable/lens/isomorphism.scrbl b/unstable/lens/isomorphism.scrbl index 26c23bf..29393c8 100644 --- a/unstable/lens/isomorphism.scrbl +++ b/unstable/lens/isomorphism.scrbl @@ -49,6 +49,7 @@ example, are defined like this: @deflenses[[string->symbol-lens symbol->string-lens number->string-lens string->number-lens list->vector-lens vector->list-lens - list->string-lens string->list-lens]]{ + list->string-lens string->list-lens + hash->list-lens list->hash-lens]]{ Isomorphim lenses for @racket[string->symbol], @racket[number->string], and so on. } diff --git a/unstable/lens/isomorphism/base.rkt b/unstable/lens/isomorphism/base.rkt index be8c779..4da233e 100644 --- a/unstable/lens/isomorphism/base.rkt +++ b/unstable/lens/isomorphism/base.rkt @@ -10,6 +10,7 @@ number->string-lens string->number-lens list->vector-lens vector->list-lens list->string-lens string->list-lens + hash->list-lens list->hash-lens )) (require racket/match @@ -43,6 +44,8 @@ (isomorphism-lenses list->vector vector->list)) (define-values [list->string-lens string->list-lens] (isomorphism-lenses list->string string->list)) + (define-values [hash->list-lens list->hash-lens] + (isomorphism-lenses hash->list make-immutable-hash)) ) (module+ test From 3bf7dedfa799b54e61bb42f2e22de2b25de22ac2 Mon Sep 17 00:00:00 2001 From: AlexKnauth Date: Wed, 19 Aug 2015 15:46:17 -0400 Subject: [PATCH 4/4] Revert "add hash->list-lens and list->hash-lens" This reverts commit d10c85480f56bfe2c36cdd74be0476894b6803bd. --- unstable/lens/isomorphism.scrbl | 3 +-- unstable/lens/isomorphism/base.rkt | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/unstable/lens/isomorphism.scrbl b/unstable/lens/isomorphism.scrbl index 29393c8..26c23bf 100644 --- a/unstable/lens/isomorphism.scrbl +++ b/unstable/lens/isomorphism.scrbl @@ -49,7 +49,6 @@ example, are defined like this: @deflenses[[string->symbol-lens symbol->string-lens number->string-lens string->number-lens list->vector-lens vector->list-lens - list->string-lens string->list-lens - hash->list-lens list->hash-lens]]{ + list->string-lens string->list-lens]]{ Isomorphim lenses for @racket[string->symbol], @racket[number->string], and so on. } diff --git a/unstable/lens/isomorphism/base.rkt b/unstable/lens/isomorphism/base.rkt index 4da233e..be8c779 100644 --- a/unstable/lens/isomorphism/base.rkt +++ b/unstable/lens/isomorphism/base.rkt @@ -10,7 +10,6 @@ number->string-lens string->number-lens list->vector-lens vector->list-lens list->string-lens string->list-lens - hash->list-lens list->hash-lens )) (require racket/match @@ -44,8 +43,6 @@ (isomorphism-lenses list->vector vector->list)) (define-values [list->string-lens string->list-lens] (isomorphism-lenses list->string string->list)) - (define-values [hash->list-lens list->hash-lens] - (isomorphism-lenses hash->list make-immutable-hash)) ) (module+ test