Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to traverse Record types? #78

Open
cowboyd opened this issue Apr 9, 2021 · 7 comments
Open

How to traverse Record types? #78

cowboyd opened this issue Apr 9, 2021 · 7 comments

Comments

@cowboyd
Copy link

cowboyd commented Apr 9, 2021

Is there the equivalent of the array value elems() traversal for Record values? I'm thinking things like keys(), values(), and entries().

Also, if you want to compose optics that are not included in the builder syntax is there an "escape hatch"? In other words, how would I define a values() traversal in user-land that didn't require a change to optics-ts itself?

@cowboyd
Copy link
Author

cowboyd commented Apr 10, 2021

Ok, I think this is at least one answer to my own question.

You can make the entries traversal by composing a object -> entries iso with the elems traversal. keys and values are just a simple composition of nth() with the entries.

import { optic } from 'optic-ts';

let entries = optic()
  .iso(
    (o) => Object.entries(o),
    (entries) => entries.reduce(
      (o, [k, v]) => Object.assign(o, { [k]: v })
      , {}))
  .elems()
 
let keys = entries.nth(0)
let values = entries.nth(1)

Wow, that felt great! I think this is the first optics library where I was actually able to figure it out on my own. Congratulations on making a really nice API.

Have you considered adding an entries traversal or iso like the above to the Optic builder interface?

@akheron
Copy link
Owner

akheron commented Apr 11, 2021

Nice! I can add the record traversals.

I don’t think there’s a way to amend the interface with new optics. However, I’m working on a new API in which optics are just functions or values instead of object methods. There you could just create new optics and use them without having to worry about any builders.

Here’s one example usage of the new API: https://github.com/akheron/optics-ts/blob/floating/src/floating/valueOr.spec.ts#L8

@cowboyd
Copy link
Author

cowboyd commented Apr 11, 2021

I'll have a look. I was playing around with them and I did tweak the entries() iso just a bit to support removing a specific value or key by only reconstructing the entry if it has two elements.

Here's the playground I was working with if it helps https://runkit.com/cowboyd/optics-ts-record-traversal

When do you think the new API will come out?

@cowboyd
Copy link
Author

cowboyd commented Apr 11, 2021

Also, fwiw, I don't mind the builder syntax so much since you've included top-level functions to use once you've constructed the lens.

@mwisnicki
Copy link

How do you type this correctly in TypeScript? I've tried but failed :(

@pkuprys
Copy link

pkuprys commented Aug 31, 2023

I was wondering if there was any movement on implementing the records() traversal?

@akheron
Copy link
Owner

akheron commented Sep 3, 2023

There's PR #81, but at least back then the TS compiler couldn't typecheck that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants