jackfirth / lens

A Racket package for creating and composing pure functional lenses
Other
73 stars 8 forks source link

hash->set isomorphism #199

Open jackfirth opened 8 years ago

jackfirth commented 8 years ago

It should be easy to convert a hash to a set of key-value pairs. Note that it should create a set, not a list, because a list would introduce ordering information that wouldn't be present in the hash. Hash keys have no particular ordering, they're only guaranteed unique from each other.

> (lens-view hash->set-lens (hash 'a 1 'b 2 'c 3))
(set '(a . 1) '(b . 2) '(c . 3))
> (lens-set hash->set-lens (hash 'a 1 'b 2 'c 3) (set '(foo . 1) '(bar . 2) '(baz . 3)))
(hash 'foo 1 'bar 2 'baz 3)

This would be very useful, as it would allow for easy hash re-keying which is a task that's cumbersome with traditional non-lens functional programming manipulations:

> (define (rekey a-hash key->new-key)
    (define rekey-set
      (compose list->set (set-map _ (lens-transform first-lens _ key->new-key))))
    (lens-transform hash->set-lens a-hash rekey-set))
> (rekey (hash 'a 1 'b 2 'c 3) symbol->string)
(hash "a" 1 "b" 2 "c" 3)
AlexKnauth commented 8 years ago

In addition to that, rekey could even be made into a lens like this: (Edited)

> (define (rekey-lens key->new-key-lens)
    (lens-zoom hash->set-lens
               (set-mapper-lens (lens-zoom car-lens key->new-key-lens))))

This would need a set-mapper-lens, which I think would have to go from sets to sets instead of sets to lists (sets to lists is what set-map does). I opened https://github.com/jackfirth/lens/issues/200 about that.

(Edit: this pattern was replaced by the outer use of lens-zoom) It also occurs to me that this pattern of

(lens-thrush an-iso-lens some-transformation-lens (isomorphism-inverse an-iso-lens))

Is just like the local-transform combinator from pict3d. It might be useful to have a lens version of that. (Edit: lens-zoom is now similar to a lens version of that.)