Created
December 22, 2023 04:13
-
-
Save nothingrealhappen/66b32313dd7cb2d2b3fe1697ddc8b58b to your computer and use it in GitHub Desktop.
fp-ts sample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: '[email protected]', | |
}; | |
// 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: '[email protected]' }) | |
: 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