Hacker News new | ask | show | jobs
by zimpenfish 2604 days ago
Apologies, I know very little Haskell - does that example mean that `computeSecond` will always be called, even if `computeFirst` failed? If it does, it's not the same as the Go code which will not call `computeSecond` in that case (which might be a requirement - who knows?)

I'm also assuming that `f first second` will return (an error monad?) if either of `first` or `second` are (an error monad?) - is that right?

3 comments

In the error monad above, computeSecond will not be called if computeFirst failed. But in other monads (which have the same syntax) computeSecond MAY be called depending on the rules of composition.

return is a bit of a misnomer in Haskell -- it really means "wrap this value in the monad supplied by the context." So as other commenters have mentioned, f(...) cannot fail. Non-monadic Haskell functions never use return.

If f could fail and you indeed wanted to propagate its error if it did fail, you could write the code as

    do first <- computeFirst
       second <- computeSecond
       f first second
It will not, because code inside a do-block is sequenced. The value `first` in the line `first <-computeFirst` is a non-error value. If computeFirst fails, the value does not exist (because computeFirst must return either an error or a non-error value), and so the whole computation fails.
This version of f can't fail, so "return" wraps its value in the same monad. Normally the "do" block would end by getting a monad from f, just as the Go version would normally let f return an error.