4 ms·
If anything the real lesson here is that you shouldn't try to lift your functions manually in the presence of a Monad. Monads tend to be somewhat 'infectious' i
by shiandow 3y ago
If anything the real lesson here is that you shouldn't try to lift your functions manually in the presence of a Monad. Monads tend to be somewhat 'infectious' in that anything that touches the Monad will need to be monadic. It's the reason why 'nullable' and 'async' can end up transforming most of the code-base to support their use.
And if you are going to write a sum type do it properly. If the language doesn't provide sum types but does have function types just use the category theory definition:
function maybeWithUser<T>(withUser: User => T, default: () => T): T {
if (!loggedIn) return default()
return withUser(fetchUser());
}
Wrap this in a class if you really want to, but the idea is the same. This then results in pretty much the code he lists in example 1, exactly because most of the functions are just regular functions:
function Page() {
const bestFriends = maybeWithUser(user => {
const friends = getFriends(user);
const bestFriends = filterBestFriends(friends);
return render(bestFriends);
}, null);
return <>
{bestFriends}
</>;
}
Of course sometimes it's better to just use what you have rather than try to use language features that aren't quite there. It helps if you can recognise what's going on though.