
Railway oriented programming - douche
https://fsharpforfunandprofit.com/posts/recipe-part2/
======
enricosada
I really think that's an useful tutorial for all languages with exceptions (
that's an exceptional event ) and normal control flow ( application error,
validation, retry ).

Like that code become really simple, but more expressive than returning an int
error code each function. A function can return an error with messages or
message+data or message+retrycount etc.

With F# (can be done in other languages obv) it's really easy to have
different success/failure return types ( amazing type inference ) without
writing too much code or having issues with maintenance ( the compiler does
his job for us ).

Like that, it's easy to create simple pure function, easier to test and reason
about.

~~~
logicallee
>for all languages with exceptions ( that's an exceptional event )

Unless, like me, you expect the unexpected.

    
    
      // if we're still here, guess it worked!
    
      return retval;
      }

------
Animats
The gyrations needed for error handling in functional programming are painful.
As Rust libraries become more functional, Rust is getting more of those
problems.

The problems created by not having exceptions are tougher than the problems
created by having exceptions.

~~~
techdragon
Erlang style "fail noisily and let the supervisor handle it" is quite a solid
way to deal with "exception handling bloat" in any paradigm, functional or
otherwise... The hard part is finding a way to create effective layers of
supervision.

~~~
hvidgaard
An exception is a noisy failure, and the supervisor is whatever try/catch that
it bubles up to. Still, Erlang style has it's own complexities. It is in
essence a network of micro services, and creating that overlay network and
manuvering in it isn't simple.

------
agumonkey
Pardon the unwise bit of word play
[http://www.calcentral.com/~monadrailway/Monad/Welcome.html](http://www.calcentral.com/~monadrailway/Monad/Welcome.html)

To be combined with Amtrak logo obviously.

ps: Dan Pinoni had an implementation running on ascii
[http://blog.sigfpe.com/2006/08/you-could-have-invented-
monad...](http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-
and.html)

------
jarcane
Ironically, it was accidentally trying to reinvent this pattern in Elm that
simultaneously made me give up on Elm and finally understand what good monads
are.

This is a really cool tutorial, I look forward to sinking my teeth into it.

------
pyrale
There's one thing I don't understand in the following signature provided for
bind :

    
    
      val bind : ('a -> Result<'b,'c>) -> Result<'a,'c> -> Result<'b,'c>
    

The author says that it takes one parameter, a function and returns another
function, but then why are there 3 args in the signature ?

I would have expected something like this :

    
    
      val bind : ('a -> Result<'b,'c>) -> (Result<'a,'c> -> Result<'b,'c>)
    

for something that takes a function and returns another function adapted to
the input, or something like this :

    
    
      val bind : ('a -> Result<'b,'c>) -> Result<'a,'c> -> Result<'b,'c>
    

for a function that takes a function G and an input I and applies G to I if
possible ad returns the eventual result (curried, Haskell-style).

What am I missing about F# ?

~~~
elros
I don't know much about F#, but in a language with currying, such distinction
does not exist, given f(x, y) == f(x)(y)

~~~
pyrale
My puzzlement came from the fact that :

    
    
      f(in -> out)(in') -> out 
      ==
      f((in -> out), in') -> out 
    

and

    
    
      f(in -> out) -> (in' -> out)
    

are similar. But thinking some more about it, I don't see a good reason for
which this would be a problem. This simply means that any function defined to
take [] elements is also able to take [:x] and return a function taking
[x:]...

I hadn't thought about this particular thing until now, but this kind of
halfway-through computation is interesting.

------
thinkMOAR
Every programming i do or language i use where there are linked lists i
already have to think of trains :)

------
hatsunearu
How is a binary "good vs. bad" result going to work? Don't you think it is
necessary to have many many "bad" conditions--i.e. errortypes?

You're just going to have to hide that away and that just drives this paradigm
moot.

------
cheepin
(2013)

------
bbcbasic
It's a monad tutorial that's too embarrassed to admit it.

~~~
edgyswingset
No it's not. This is a tutorial on error handling that happens to be monadic.
The emphasis is on handling errors, not talking about monads.

~~~
bbcbasic
It can be more than one thing at a time.

~~~
edgyswingset
Emphasis mine:

> It's a monad tutorial _that 's too embarrassed to admit it._

This is not a correct interpretation of the blog post. This is not a _monad
tutorial_ , this is a tutorial on error handling that happens to be monadic.

~~~
justinpombrio
> This is not a _monad tutorial_ , this is a tutorial on error handling that
> happens to be monadic.

And is, for that very reason, a great tutorial on monads, even if it's not a
_monad tutorial_.

------
transfire
This is a tutorial on how to get a nose bleed.

