Skip to content

Instantly share code, notes, and snippets.

@nothingrealhappen
Created December 22, 2023 04:13
Show Gist options
  • Save nothingrealhappen/66b32313dd7cb2d2b3fe1697ddc8b58b to your computer and use it in GitHub Desktop.
Save nothingrealhappen/66b32313dd7cb2d2b3fe1697ddc8b58b to your computer and use it in GitHub Desktop.
fp-ts sample
import { pipe } from 'fp-ts/function';
import * as O from 'fp-ts/Option';
import * as E from 'fp-ts/Either';
import * as A from 'fp-ts/Array';
import { sequenceT } from 'fp-ts/Apply';
import { flow } from 'fp-ts/function';
import * as t from 'io-ts';
// Example of a complex validator using io-ts
const UserProfile = t.type({
name: t.string,
age: t.Int, // Int is a refinement of number which ensures it's an integer
email: t.string,
});
// Let's assume we have some user input that needs validation
const userInput = {
name: 'Alice',
age: 30,
email: 'alice@example.com',
};
// Function to simulate an API call that might fail
function fetchUserFromAPI(userId: number): E.Either<Error, unknown> {
return Math.random() > 0.5
? E.right({ name: 'Bob', age: 28, email: 'bob@example.com' })
: E.left(new Error('Failed to fetch user'));
}
// Function to validate user data with io-ts
function validateUser(input: unknown): E.Either<t.Errors, t.TypeOf<typeof UserProfile>> {
return UserProfile.decode(input);
}
// Helper function to transform Either to Option
const eitherToOption = <E, A>(e: E.Either<E, A>): O.Option<A> =>
pipe(
e,
E.fold(
(_, __) => O.none,
(a) => O.some(a)
)
);
// Simulate fetching multiple users and validating them
const userIds = [1, 2, 3, 4];
const validatedUsers = pipe(
userIds,
A.map(fetchUserFromAPI),
A.map(eitherToOption),
A.compact, // Remove None values
A.map(validateUser)
);
// Function to combine several Options into one
const combineOptions = sequenceT(O.Apply);
// Example of using combinators to process data (e.g., finding users over 25)
const findUsersOver25 = (users: Array<E.Either<t.Errors, t.TypeOf<typeof UserProfile>>>): Array<t.TypeOf<typeof UserProfile>> =>
pipe(
users,
A.map(E.fold(
() => [],
(user) => user.age > 25 ? [user] : []
)),
A.flatten
);
// Using the functions to process the user data
const result = pipe(
validatedUsers,
(users) => findUsersOver25(users)
);
// Showcasing advanced composition using fp-ts
const processUserData = flow(
A.map(fetchUserFromAPI),
A.map(eitherToOption),
A.compact,
A.map(validateUser),
findUsersOver25
);
// Process the list of userIds
const finalResult = processUserData(userIds);
// Print out the results of our operations
console.log('Validated Users:', JSON.stringify(result, null, 2));
console.log('Final Result:', JSON.stringify(finalResult, null, 2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment