3

Hedgehog has an HTraversable class defined like this:

-- | Higher-order traversable functors.
--
class HTraversable t where
  htraverse :: Applicative f => (forall a. g a -> f (h a)) -> t g -> f (t h)

Which is used with their Var type for parameterizing a type over whether values are concrete or abstract. t has kind (* -> *) -> * and is a higher order functor although they don't actually have that class, f, g and h have kind * -> *. I've seen the same thing defined in a few different libraries.

Is there a way to get an optic out of this? I confess I don't know what that would even do, and I'm not super comfortable with lenses or regular Traversable either.

Shersh
  • 9,019
  • 3
  • 33
  • 61
Echo Nolan
  • 1,111
  • 1
  • 11
  • 23

1 Answers1

1

Sure.

type HTraversal s t a b =
    forall f. Applicative f => (forall x. a x -> f (b x)) -> s -> f t

htraverse :: HTraversable t => HTraversal (t a) (t b) a b

Remember, lens's Traversal comes about by taking the type of traverse and letting the t a and t b types vary, viewing the traversable not as a polymorphic container but as a monolithic blob.

How useful HTraversal is, I dunno. You can't compose them nicely with (.).

Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
  • Hmm, interesting. So there's a corresponding thing, but it doesn't really fit with the other optics. I wonder if there are a set of "higher order optics" that this does work with. – Echo Nolan Oct 31 '17 at 21:29
  • `HTraversable` is for objects in the category of functors from the functor category to Hask. You can work with the category of _endofunctors_ on the functor category (such as monad transformers), for which `Traversable` would look like `itraverse :: Applicative f => (forall x. a x -> f (b x)) -> (forall x. s x -> f (t x))`. Traversals of this type do compose with `(.)`, and you can build out prisms etc too. Neither `HTraversable` nor `ITraversable` would interoperate with `lens`, though, because they're built on a different category. – Benjamin Hodgson Nov 01 '17 at 01:24