Rewriting this in terms of other arrows isn't too hard:
data (Arrow a) => CountArrow a b c = CountArrow (a (b,Int) (c,Int))
Mostly you can use the standard arr function to raise an arbitrary function into an arrow, but in particular implementing first requires using ghc's extended arrow syntax.
instance (Arrow a) => Arrow CountArrow a b c where
arr f = ArrowCounted (arr (\(x,n) -> (f x,n)))
(ArrowCounted f1) >>> (ArrowCounted f2) = ArrowCounted (f1 >>> f2)
first (ArrowCounted f) =
ArrowCounted (proc ((x,y),n) -> do (x',n') <- f -< (x,n)
returnA -< ((x',y),n'))
In particular, it helps to read proc as "lambda", and the funky -< operator as appearing in between a function and its parameter; then this reads just like monadic "do" syntax.
(The other useful comment is that, having realized where the arrow could be useful at all, it's taken me a morning to come up with a couple of ways to write this class; the IO monad means that any Haskell work uses monads from day one and things like lists and Maybe are usefully monads, but it took years to actually get a handle on it.)
no subject
Rewriting this in terms of other arrows isn't too hard:
Mostly you can use the standard arr function to raise an arbitrary function into an arrow, but in particular implementing first requires using ghc's extended arrow syntax.
In particular, it helps to read proc as "lambda", and the funky -< operator as appearing in between a function and its parameter; then this reads just like monadic "do" syntax.
(The other useful comment is that, having realized where the arrow could be useful at all, it's taken me a morning to come up with a couple of ways to write this class; the IO monad means that any Haskell work uses monads from day one and things like lists and Maybe are usefully monads, but it took years to actually get a handle on it.)