3 ms·
What happens when you mix what <- means : do a <- getData // this is a awaiting a future b <- getMoreData a // this is looping a list c <- getMoreData
by julienfr112 9y ago
What happens when you mix what <- means :
do
a <- getData // this is a awaiting a future
b <- getMoreData a // this is looping a list
c <- getMoreData2 b // this is null checking
d <- getEvenMoreData a c // this is awaiting another future
print d
Monads' hell, isn't it ?
- mdellabitta 9y agoBeing able to combine monads like this is part of the point.
- julienfr112 9y agoit means that the fact that the monad is looping or checking for null or awaiting a future is coded in the function itself, and hidden when reading the for loop. When types are heavily overloaded, it can take minutes to know if we are looping a iterable, awaiting a futurable or checking for null a maybeable. And what about a Maybe(List) ? a Future of list ? Common, how is this not Hell ?
- igorbark 9y agoHaskell's type inference is optional: if you felt the above code is difficult to understand, you could manually specify the type of each statement. In a language with a less powerful type system, you could write the same information in comments, but then the compiler wouldn't warn you if you accidentally changed the side effects of a statement.
- foldr 9y agoBut you can't combine monads like that in Haskell.
- harpocrates 9y agoThis is not possible in regular Haskell. For one, it isn't obvious how to do such a desugaring and, even if it were, this is pretty gross. I remember a co-worker finding some weird combination of old extensions which allowed you to do something gross-ish of this form. I've _never_ seen such a thing in real life. The only practical issue that comes close to this is sometimes trying to figure out _what_ monad a particular `do` block is running with (my mental type inference falls short of the compiler's).
- julienfr112 9y agoi'm currently deciphering such code in scala ...
- hexointed 9y agoI believe that monad transformers can be used to solve this issue.
- tominated 9y agoThe do block syntax is actually just a syntax sugar for the `bind` function (also written `>>=`). The above would de-sugar to something like this (I may have syntax wrong): getData >>= \a -> getMoreData a >>= \b -> getMoreData2 b >>= \c -> getEvenMoreData a c >>= \d -> print d The type signature of the `bind`/`>>=` function requires that both sides be the same type of monad, so it won't actually typecheck unless all of the get data functions return the same type of monad (future, list, optional, etc). There's a number of ways to get around this in haskell (monad transformers, free/freer monads, etc) but they're all pretty complicated unless you're pretty familiar with the language. (Disclaimer I'm probably a little wrong in my description - I'm still learning haskell)