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

Traversal can't change type #191

Open
dawnchan030920 opened this issue May 26, 2024 · 1 comment
Open

Traversal can't change type #191

dawnchan030920 opened this issue May 26, 2024 · 1 comment

Comments

@dawnchan030920
Copy link

modify and modifyF of traversals both cannot change the type of the value. A more general function is needed.

Scenario

For example, I'm building a blog and I have a slug to some other content collection inside of a list field of a collection item. GetXXXBySlug returns Option<T> and I want the Option to wrap the entire object, and T at the same time not a string.

It requires me to perform a wrapping of a side-effect while also changing the type of the value from string to T.

Example

Change

type Series = {
    posts: {
        postSlug: string;
        subtitle?: string | undefined;
    }[];
    slug: string;
    title: string;
    description: string;
}

into

Option<{
    posts: {
        postSlug: Post;
        subtitle?: string | undefined;
    }[];
    slug: string;
    title: string;
    description: string;
}>

by using a function with the signature

string -> Option<Post>

I'm wondering if there're some good workarounds using sequence or something, but I can't figure it out because the field is very deep in the structure.

@dawnchan030920
Copy link
Author

Here's the workaround solution

  pipe(
    O.Do,
    O.bind("series", () => getSeriesBySlug(slug)),
    O.bind("posts", ({ series }) =>
      pipe(
        series.posts,
        A.traverse(O.Applicative)((post) =>
          pipe(
            getPostBySlug(post.post),
            O.map((innerPost) => ({ ...post, post: innerPost }))
          )
        )
      )
    ),
    O.map(({ series, posts }) => ({
      ...series,
      posts,
    }))
  );

But it's verbose and it forces the naming of some fields, which is not good for extending

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

1 participant