Arrow
is a useful typeclass for modeling something that behave like functions, e.g,. Function1
: A => B
, Kleisli
: A => M[B]
(also known as ReaderT
), Cokleisli
: F[A] => B
, etc. So useful, that Haskell provides a proc
notation for composing and combining Arrow
s, similar as the do
notation for sequencing monadic operations. The proc
notation comes in really handy, since without it, Arrow
s have to be used point-free, which impairs readability.
The Haskell Wikibook has a nice little example of a Hangman implementation based on an Arrow
type called Circuit
. Circuit
is basically a fancy function which takes an A
, and in addition to returning a B
, it also returns a new Circuit[A, B]
. This sounds similar as the State
monad (which returns a result and a new State
from an initial State
), and indeed, Circuit
can be used to perform stateful computations.
Both Scalaz and Cats provide the Arrow
typeclass. I wrote a Scala implementation of Arrow Hangman using Scalaz, which closely follows the Haskell implementation, except that Scala has no proc
notation (although it is possible to create one), so we resort to raw combinators like >>>
, &&&
and ***
. Itβs not too bad though, as long as we give names to intermediate steps, rather than doing all the combination in one huge expression.