Search code examples
haskellhaskell-lenscategory-theorytraversablehaskell-hedgehog

Is there a corresponding optic for higher-order traversable functors?


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.


Solution

  • 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 (.).