Monoid — wtf is it?
It's a math term used by programmers that are still virgins (haha jk).
Actually, it's a thing that you end up needing to use all the time when doing functional programming.
The reason we embraced Typescript is because it results in less runtime exceptions. Initially, it's annoying to have to define typings and you use any all the time, but eventually you end up appreciating it because it makes our programs more reliable.
Functional programming is sort of like typescript when you already use typescript. You constrain yourself to a stricter environment with more rules in exchange for more reliable programs.
One of the ways functional programming achieves this is by eliminating a lot of "forks" in the execution path. This is a term I made up but it's how I see it in my head.
In non-functional code you can do this:
async function fetchUsers(session: Session): Promise<User[]> {
const roles = session?.user?.fetchRoles();
const allow = roles?.includes("ADMIN")
// branch
if (!allow) {
throw new Error("nope")
}
try {
const res = await fetch("/api/users")
const json = await res.json()
// branch
return json.data.users;
} catch (e) {
// branch
e.message = `failed to fetch users: ${e.mgessage}`
throw e
}
}
You can imagine going down a straight road, and then depending on some condition you have to turn at a fork. This is what I mean by "forking".
Each fork increases complexity by 2, since there are now twice as many possible end states. This complexity is where unexpected errors can occur.
Also the fact that this function uses a promise would also be considered a no-no in the functional typescript school of thought. The FP philosophy says that the return type of Promise<User[]> is actually a lie, since it tells us nothing about the fact that it can throw an error, and what type of errors it can throw. Personally I 100% agree with this, and in fact it is not possible with the current state of typescript to express this natively. This is why effect-ts uses generators - which in my opinion are far superior to promises which are ugly as hell anyways, and result in endless try {} catch chains all over the place -_-
