Yep, I posted this on r/haskell and someone pointed this out, which is cool. The provided type for Peg didn't derive Enum or Bounded, but it's a good trick to know.
I'm kind of surprised that `enumerate` isn't defined in any standard libraries (as far as I know) since I need it pretty often.
After a while spent programming in Haskell you would probably develop your own mini-library of functions that make your life easier. Another one I often find useful is
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) f g = \x y -> f (g x y)
which e.g. allows you to define the absolute distance function
dist :: (Num a) => a -> a -> a
dist = abs .: (-)
A fun challenge is figuring out why the definition of (.:) is equivalent to
> A fun challenge is figuring out why the definition of (.:) is equivalent to
> (.:) = fmap . fmap
> !
Of course it's not really equivalent, since the most general type of the LHS is as you have said, whereas that of the RHS involves functor constraints; but inlining the definition of `fmap` for arrows gives the amusing definition:
(.:) = (.) . (.)
I tend to figure this sort of thing out by successive eta conversion:
\f g x y -> f (g x y)
\f g x y -> (f . g x) y
\f g x -> f . g x
\f g x -> ((f .) . g) x
\f g -> (f .) . g
\f g -> ((f .) .) g
\f -> ((f .) .)
\f -> (.) (f .)
\f -> (.) ((.) f)
\f -> ((.) . (.)) f
(.) . (.)
The downside of using (.:) is that it is used heavily in other libraries (Aeson for instance) in a very different context (field accessors, similar in look to json's `:`).