Monads IO
๐ Efficient Monads for JS: Maybe (Option) and Either (Result)
Why use this lib
- Small and Tree-Shakable. Either - 3kb minified, Maybe - 3kb minified, can be imported separately
- No dependencies.
- Memory-Efficient. 8 bytes overhead per instance (only class pointer)
- Tested. 100% coverage
- Practical. Just 2 wrappers: Either and Maybe - easy for non-fp people
Credits
Huge credit to @JSMonk. This library is based on JSMonk/sweet-monads
Docs available in his repository
๐ฆ Installation
-
Using
npm
npm i monads-io
-
Using
Yarn
yarn add monads-io
-
Using
pnpm
pnpm add monads-io
โ๏ธ Usage
// Real world example
// This maybe is not tree-shakable. Used in NodeJS code
import { Maybe } from "monads-io";
export async function getTargets(
api: TelegramAPI,
tokens: formattedText,
{ mentionLimit = 1, message = undefined as message | undefined } = {}
): Promise<Map<number, chat | undefined>> {
const mentions = getMentions(tokens).slice(0, mentionLimit);
const targets = new Map<number, chat | undefined>();
let replyTarget: [number, chat | undefined] | undefined;
const { messagesService, chatsService } = getServices(api);
...
// 1. Get message
// 2. Get message reply id (0 = no reply)
// 3. Get reply message by message id
// 4. Get reply message sender
// 5. Get his/her profile
// 6. Set local variable to profile
const reply = await Maybe.fromNullable(message)
.filter((message) => message.reply_to_message_id !== 0)
.asyncChain((message) =>
messagesService.getReply(message.chat_id, message.id)
);
const sender = await reply
.map(MemberId.fromMessage)
.tap(({ memberId }) => {
replyTarget = [memberId, undefined];
})
.asyncChain(({ memberId }) => chatsService.getById(memberId));
sender.tap((sender) => {
replyTarget = [sender.id, sender];
});
...
return replyTarget ? new Map([replyTarget, ...targets]) : targets;
}