5 ms·
> When you see a "do" block, where do you look to figure out what it's actually doing? If you need to know, you look at what consumes the result. If it's abst
by dllthomas 9y ago
> When you see a "do" block, where do you look to figure out what it's actually doing?
If you need to know, you look at what consumes the result. If it's abstract (say it's a top level binding `... -> m a` where the m is abstract) you don't need to know "what it is actually doing" - it should be correct for any choice of `m`.
Whether this stuff is easy to find/follow certainly depends on the quality of the code, as well as your experience. It's not something I struggle with, working day-to-day in Haskell.
- dmitriid 9y ago> you don't need to know "what it is actually doing" - it should be correct for any choice of `m`. I don’t know what it’s doing, but it’s correct. :-/ So what is it doing that’s correct? Or is it some abstract correctness?
- dllthomas 9y agoIt's not abstract correctness, it's satisfying contracts up to an interface. Take `sequence :: Monad m => [m a] -> m [a]` That takes a list of actions and gives us an action that runs each in turn and collects the results in order. The correctness relative to that description is clear regardless of whether each input action is threading state or handling failure or printing to the screen.
- dmitriid 9y agoThen this clearly doesn’t answer the original question, does it?
- deleted 9y ago[deleted]
- dllthomas 9y agoNot on its own. Fortunately, it wasn't the entirety of my answer to the original question. When you're writing something like `sequence`, you don't need to know the implementation of the interface you're working against. As you get comfortable in Haskell, more things are "like `sequence`". There will always be things that aren't - for those, as I said, you should look where the value is consumed. And as I neglected to say, you can always add a type annotation when things get unclear.
- dmitriid 9y agoAh, the old Java adage: any abstraction can be solved with many more layers of abstraction.
- Izkata 9y ago> If you need to know, you look at what consumes the result. If it's abstract (say it's a top level binding `... -> m a` where the m is abstract) you don't need to know "what it is actually doing" - it should be correct for any choice of `m`. That seems to explain a lot. So to make an ad-hoc version of the Elvis Operators section that's actually equivalent to the Haskell code would be more like this? ___ a ___ getData(); ___ b ___ a ___ getMoreData(); ___ c ___ b ___ getMoreData(); ___ d ___ c ___ getEvenMoreData(a); print(d);