indexM in Representable?
There should be a function called something like indexM in the Representable typeclass, with the type
indexM :: (Representable f, Monad m) => f a -> Rep f -> m a
Its default definition would simply be
indexM f k = return $ index f k
But for some Representables, it could produce a more defined result, for the same reasons as in Data.Vector. An example for Product:
indexM (Pair a _) (Left i) = indexM a i
indexM (Pair _ b) (Right j) = indexM b j
The result passed to return contains no reference to the original Product value. This could be a win for people using Representables for memoization.
Monad is overkill; Applicative will do. Furthermore, this suggests a subclass:
class (Representable t, Traversable t) => TravRep t where
tabulateA :: Applicative f => (Rep t -> f a) -> f (t a)
tabulateA = sequence . tabulate
But the tabulation and sequencing can be fused:
data Pair a = Pair a a deriving Traversable
instance Representable Pair where
type Rep Pair = Bool
instance TravRep Pair where
tabulateA f = liftA2 Pair (f False) (f True)
Notably, using data Box a = Box a as the Applicative, you can eagerly perform some computation at each value while building the container. For example, you can eagerly pull elements out of one Representable functor and into a new one of a different type.