Skip to content

Instantly share code, notes, and snippets.

@YBogomolov
Last active September 9, 2023 08:29
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YBogomolov/03b742e68f35ee963d2097814200b269 to your computer and use it in GitHub Desktop.
Save YBogomolov/03b742e68f35ee963d2097814200b269 to your computer and use it in GitHub Desktop.
Tagless Final example with fp-ts
import { HKT, Type, URIS } from 'fp-ts/lib/HKT';
import { identity, Identity, URI } from 'fp-ts/lib/Identity';
import { Monad, Monad1 } from 'fp-ts/lib/Monad';
// Task: get all users named 'John' and make them admins
interface User {
id: number;
name: string;
age: number;
isAdmin: boolean;
}
const fakeUsers: User[] = [
{
id: 1,
name: 'John Connor',
age: 32,
isAdmin: false,
},
{
id: 2,
name: 'John Smith',
age: 18,
isAdmin: false,
},
{
id: 3,
name: 'Mark Brian',
age: 28,
isAdmin: false,
},
];
interface UserOps<M> {
search: (params: Partial<User>) => HKT<M, User[]>;
makeAdmins: (users: User[]) => HKT<M, User[]>;
save: (users: User[]) => HKT<M, boolean[]>;
}
interface UserOps2<M extends URIS> {
search: (params: Partial<User>) => Type<M, User[]>;
makeAdmins: (users: User[]) => Type<M, User[]>;
save: (users: User[]) => Type<M, boolean[]>;
}
interface App<M> extends UserOps<M>, Monad<M> { }
interface App2<M extends URIS> extends UserOps2<M>, Monad1<M> { }
interface Program {
getMain<M extends URIS>(M: App2<M>): () => Type<M, boolean[]>;
}
class Program {
getMain<M>(M: App<M>): () => HKT<M, boolean[]> {
return () => {
const johns = M.search({ name: 'John' });
const admins = M.chain(johns, M.makeAdmins);
return M.chain(admins, M.save);
};
}
}
const testInstance: App2<URI> = {
...(identity as Monad1<URI>),
search: (params: Partial<User>) => identity.of(fakeUsers.filter((u) => u.name.includes(params.name))),
makeAdmins: (users: User[]) => identity.of(users.map((u) => ({ ...u, isAdmin: true }))),
save: (users: User[]) => identity.of(users.map((u) => u.isAdmin)),
};
const main = new Program().getMain(testInstance);
const result = main() as Identity<boolean[]>;
console.log(result.value);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment