Re:Functional exceptionless error-handling with optional and...
by greydius on Sunday December 03, 2017 @02:27PM
(#15839021)
A lot of people dislike the terseness of that style (especially the use of operators.) I'm not one of those people, but I can understand their point of view. Fortunately, Haskell also lets us write code in a way that managers can understand.
getCuteCat img = do
cropped <- findCat img
withTie <- addBowTie cropped
withSparkles <- makeEyesSparkle withTie
return (addRainbow (makeSmaller withSparkles))
Re:Functional exceptionless error-handling with optional and...
by runeks on Sunday December 03, 2017 @02:58PM
(#15839202)
And, with this translation, I hope everyone can see how exceedingly simple the >>= operator is: “take the return value of what’s to the left of me and deliver it as an argument to the function to the right of me”.
(Nitpick: if we’re translating kccqzy’s example verbatim, the last line shouldn’t include return, since — as per his definition — addRainbow is monadic)
Re:Functional exceptionless error-handling with optional and...
by davidgay on Sunday December 03, 2017 @02:49PM
(#15839157)
However this style breaks down as soon as you have to do something more complicated than thread a single value, or have to do something more complicated than pass failures through.
Re:Functional exceptionless error-handling with optional and...
by haar on Sunday December 03, 2017 @03:21PM
(#15839352)
We've been using this style a lot in Elixir via the `with` macro
def get_cute_cat(image_id) do
with {:ok, cropped} <- find_cat(image_id),
{:ok, with_tie} <- add_bowtie(cropped),
{:ok, with_sparkles} <- make_eyes_sparkle(with_tie)
do
with_sparkles
|> make_smaller()
|> add_rainbow()
end
end
If any of the values on the rhs of a `<-` cannot be pattern matched, it returns up the returned value. This value can be pattern matched easily inside an `else` clause underneath the main block. The use of the `:ok,` vs `:error,` tuple convention allows multiple values to be destructured and passed around if needed (rather than an optional type).If you find the code getting unwieldily, as runeks said you can break it down into simpler constructs.
Re:Functional exceptionless error-handling with optional and...
by runeks on Sunday December 03, 2017 @03:03PM
(#15839225)
Code can always be broken up into simpler sub-components. The more you logically compartmentalize your code, the more it lends itself to these simple transformations. At the end of the day, you — not the problem you’re trying to model — decide how much you want to do in each function.
Re:Functional exceptionless error-handling with optional and...
by vikiomega9 on Sunday December 03, 2017 @04:34PM
(#15839727)
Naive question, how do I figure out in which part of the chain a null had occured? Or is the assumption that you'd establish only valid inputs and therefore never have a chance for this to happen?
Re:Functional exceptionless error-handling with optional and...
by kccqzy on Sunday December 03, 2017 @05:44PM
(#15840099)
The Maybe monad doesn’t have this feature. It’s purposefully simple: the value is either present or absent.
If you want different errors, use the Either monad. It basically means either the value you want is there, or it’s not there but there’s an explanation. Chaining works just as well for the Either monad.
Re:Functional exceptionless error-handling with optional and...
by amluto on Sunday December 03, 2017 @04:54PM
(#15839832)
> Yes Rust has .and_then which is same as >>= (sometimes also called flatMap or bind), but still the syntax isn’t lightweight enough.
Rust has try! and ?. The latter is quite lightweight.
Yes this example uses monads, and there’s a reason why monads aren’t that popular in other languages. Most of the time you also need parenthesis-less function application, currying, and lightweight lambdas to make monad-heavy code syntactically acceptable. Yes Rust has .and_then which is same as >>= (sometimes also called flatMap or bind), but still the syntax isn’t lightweight enough.
I wish people could just stop copying this idea from Haskell and use what’s reasonable in their language. Shoehorning monads and monad-heavy code into a typical language isn’t reasonable.