Convert a collection of Either<A, B> into an Either<A[], B[]> array

Looking to convert an array of type Either<A, B>[] into Either<A[], B[]>

The goal here is to gather all the left-values (errors) if there is at least one, otherwise return all right answers.

This task may appear straightforward, but my current attempt seems overly complex:

const compress = <A, B>(arr: E.Either<A, B>[]): E.Either<A[], B[]> => 
  A.reduce(
    E.right([]),
    (acc: E.Either<A[], B[]>, v: E.Either<A, B>) => 
    E.match(
      (a: A) => E.match((aar: A[]) => E.left([...aar, a]), 
                        (bar: B[]) => E.left([a]))(acc),
      (b: B) => E.match((aar: A[]) => E.left(aar), 
                        (bar: B[]) => E.right([...bar, b]))(acc)
    )(v)
   )(arr);

There has to be a simpler way to accomplish this objective.

Answer №1

You can utilize the separate function to gather the lefts and rights in an array of Eithers. While this may suffice, you can achieve the precise type you desire by following:

import { separate } from 'fp-ts/Array';
import * as E from 'fp-ts/Either';
import { pipe } from 'fp-ts/lib/function';

declare const es: Array<E.Either<number, string>>;

const output: E.Either<string[], number[]> = pipe(
  es,
  separate,
  // Assuming you want the either to be on the left if any result was left.
  (s) => s.left.length > 0 ? E.left(s.left) : E.right(s.right),
);

Another option is sequenceArray, which serves as a shortcut when consolidating errors from various sources. However, it converts to a left as soon as a single left is found, so you won't receive all of the left values back at once (which could be a drawback if you need full visibility into all the lefts).

const output2: E.Either<string, readonly number[]> = pipe(
  es,
  E.sequenceArray,
);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to implement this (click) function in Angular?

My goal is to create a set of three buttons with a (click) function attached to each. Initially, when the page loads, the first button should be selected while the other two are unselected. If I click on an already selected button, it should remain selecte ...

Error with the type of CanvasGradient in the NPM package for converting text to image

I attempted to generate an image using a specific text by utilizing npm's text-to-image package, but encountered an error during typescript compilation. The errors I encountered upon running the typescript compilation command are related to files with ...

Exploring the integration of the mongodb-stitch library within an Angular 4 application

I have been experimenting with the MongoDB Stitch service in Angular, and so far I have successfully implemented the service. However, the only way I have managed to connect to the service is by adding the js library hosted on AWS directly into the html pa ...

Obtain characteristics of the primary element in Ionic version 2 or 3

After creating and opening my Sqlite database and saving the SQLiteObject in a variable within my app.component.ts, I now need to retrieve these attributes in my custom ORM. The ORM extends to other providers to describe the title and field of my tables. ...

Custom attributes given to Stencil web components in Vite/Vue3 will not trigger any reactions

Short backstory I initially set up my project with a vue-cli environment using Vue 2 and options-api. Recently, I decided to transition to create-vue, which is based on Vite with Vue 3 and Typescript. To incorporate web components from Stencil into my pro ...

The custom validation feature in Angular 4 is failing to function as expected

Currently, my focus is on Angular 4 where I have developed a custom validator for checking CGPA values (to ensure it is between 2.0 and 4.0). Although the predefined `Validators.required` works fine, my custom validator seems to be not triggering as expect ...

The role of providers in Angular applications

After creating a component and service in my project, I followed the documentation's instruction to include the service in the providers metadata of the component for injection. However, I found that it still works fine even without mentioning it in t ...

When using Reactjs, it is not possible to update the state using useState within the handleSubmit function

I've encountered a puzzling error and could use some assistance in understanding it better. After calling setServerList(data.data), the data still appears empty when I attempt to use it. export const KernelUpdateSearch = (props: RouteComponentProps) ...

In Typescript, null values are allowed even when the type is set to be non-nullable

Can someone explain why the code below allows for null in typescript, even though number is specified as the type: TS playground // Not sure why null is accepted here when I've specified number as the type const foo = (): number => 1 || null ...

Angular not triggering event upon changing URL fragment subscription

I'm currently using Angular 13 and attempting to subscribe to the ActivatedRoute 'fragment'. However, I am facing an issue where the subscription only receives a notification when the page initially loads, and does not update when the fragme ...

Developing custom events in an NPM package

Developing a basic npm package with signalr integration has been my recent project. Here's how it works: First, the user installs the package Then, the package establishes a connection using signalr At a certain point, the server triggers a function ...

Adding a class to a child component layout from a parent component in Angular 12 and Typescript can be achieved by using the ViewChild decorator

Incorporating the child component into the parent component is an important step in the structure of my project. The dashboard component serves as the child element, while the preview component acts as the parent. Within the parent (preview) component.htm ...

Limiting Material UI Tags - Is there a way to pull all information from the database by simply clicking on the initial tag that says "select all"?

Looking to create an MUI - limit tag. Essentially, I want the user to be able to click on the "select all" element and have all the rest of the data added to small chips at once. If you want to see a demo of what I'm trying to achieve, check out this ...

Encountering overload error with Vue 3 and Axios integration

Currently utilizing Vue 3, Vite, Axios, and TypeScript. While my function functions properly in development, it throws an error in my IDE and during the build process. get count() { axios({ method: "get", url: "/info/count", h ...

The Next.js API has a mysterious parameter that remains undefined

I currently have a component implemented import React, { useEffect } from "react"; import styles from "../styles/success.module.css"; import { useRouter } from "next/router"; import axios from "axios"; const Success ...

What could be causing my NextJS application to not recognize the _document.tsx file?

Seeking assistance in understanding why my _document.tsx is not loading properly within my nextJS application. My Attempts So Far I have been diligently following the NextJS documentation for creating a custom _document.js. Despite my efforts, I am unable ...

The type '{}' is lacking the 'submitAction' property, which is necessary according to its type requirements

I'm currently diving into the world of redux forms and typescript, but I've encountered an intriguing error that's been challenging for me to resolve. The specific error message reads as follows: Property 'submitAction' is missing ...

Issue with TypeScript Decorator Not Properly Overriding Get/Set Functions for Instance Properties

I'm struggling with creating a TypeScript decorator that modifies the get method for a property within a class. The issue I'm facing is getting it to affect instances of the class. Below is an example scenario: function CustomDecorator() { r ...

Incorporate personalized No Data Available message in ngx-datatable

How can I customize the no data message for ngx-datatable? I want to avoid displaying the default message that comes with it. Here is what I have attempted so far: <div *ngIf="showTable"> <ngx-datatable [rows]="rows"> ...

Transforming the data type of a variable

Recently, I decided to switch my file name from index.js to index.ts. Here's an example of the issue I'm facing: let response = "none" let condition = true if(condition){ response = {id: 123 , data: []} } console.log(response) Howev ...