38 ms·
This analogy/metaphor is usually represented in code via an interface called MonadFail (e.g. in Haskell https://hackage.haskell.org/package/base-4.17.0.0/docs/C
by chriswarbo 4y ago
This analogy/metaphor is usually represented in code via an interface called MonadFail (e.g. in Haskell https://hackage.haskell.org/package/base-4.17.0.0/docs/Control-Monad-Fail.html#t:MonadFail https://hackage.haskell.org/package/base-4.17.0.0/docs/Contr... and Scala https://www.javadoc.io/doc/org.typelevel/cats-docs_2.13/latest/cats/MonadError.html https://www.javadoc.io/doc/org.typelevel/cats-docs_2.13/late... )
Some related points:
- Sequential composition (putting one piece of track after another) is captured by the Monad interface. Monad is more general than MonadFail, since it includes things which don't fit into the 'two track' analogy.
- Concurrent composition (running separate tracks side-by-side) is captured by the Applicative interface. Applicative is more general than Monad, since it includes things which can't be sequenced.
Where possible, we should try to use the most-general interface we can: this makes our code usable in more scenarios, and also prevents us calling inappropriate methods. In fact, this article's example of validating multiple fields not a good use-case for 'railway oriented programming', since it will abort after detecting one failure!
A better approach is something like the Validated type from Scala's cats library https://www.javadoc.io/doc/org.typelevel/cats-docs_2.13/latest/cats/data/Validated.html https://www.javadoc.io/doc/org.typelevel/cats-docs_2.13/late...
Validated can represent success/failure, but it does not provide the Monad interface; hence we cannot sequence one check after another. The only way to combine multiple Validated results is via its Applicative interface, which performs all the checks concurrently: if they're all successful, the result is successful; if any fails, the result contains all of the failures.
In the article's example, if we have an invalid email address and a missing first name, we'll only be told about the email address. In the Applicative approach, we'll be told about both problems.
(Note that we can also define an ApplicativeFail interface; but I don't think the railway metaphor makes sense in that case)