Monad annoyance
Monad is a big unnecessary word but maybe I just mean something more like 'chainable Promise-like thing', since I'm coming from TypeScript land. What I'm annoyed by is that for years I've had a situation like this:
With these functions:
async function getOrganization(name: string): Promise<Organization>
async function getMembers(orgId: string): Promise<Members[]>I'll want to do something like 'get an organization and its members'. So in beautiful elegant point-free style I could write:
const list = getOrganization(name).then(org => getMembers(org.id));But this produces only the members list. I don't want chains to always replace the previous chained 'thing', in many cases I want them to add to it. So I'll end up doing:
const list = getOrganization(name).then(org => {
return getMembers(org.id).then(members => {
return {
members,
org
}
})
});Much less beautiful, right? This happens all the time with Promise chaining as well as when I use neverthrow, and it's a little more cumbersome in the neverthrow case. I kind of want a 'combiningThen' method that would work like:
const [org, members] = getOrganization(name).combine(org => getMembers(org.id));Even Effect, which is a swiss-army knife of every possible functional-programming concept, doesn't have something that seems obviously like this. Maybe chaining Effect.all would do it?
Having simple dependencies on earlier results is always the thing that makes elegant FP-flavored code look funky.