4 ms·
This is mostly useful for reusable boilerplate. For example, if I have a list and want to map over it with a function, I can call normal `map`. But if I want to
by lalaithion 7y ago
This is mostly useful for reusable boilerplate. For example, if I have a list and want to map over it with a function, I can call normal `map`. But if I want to map over it with a function that doesn't return a normal value, I can get something weird. With promise, for example, I might end up with a list of promises, where what I want is a promise containing a list. If I didn't have monads, I would have to write a function that manually took each value out of the list, awaited it, and put that value into a new list that will be returned from that function.
In Haskell, that function is just called `mapM`, and it's consistent whether you're working with exceptional cases (Either String a), nullable cases (Maybe a), IO (IO a), Promises (Async a), or even weirder things.
This is actually a huge problem for the Java Streams API, because Java's checked exception feature is sort of like most monads. You can't call a function that throws an exception inside of a function that doesn't, except by using some weird incantation. (You can think of `try` as being a built in syntax for "running" the exception monad). Which means that you can't call an exception throwing function in `Stream::map`. Instead, you have to do something really ugly. https://www.reddit.com/r/java/comments/49yjqf/tunnelling_exceptions_in_stream_lambdas/ https://www.reddit.com/r/java/comments/49yjqf/tunnelling_exc...