Search code examples
haskelltypestraversaltypeclassparametric-polymorphism

Is there something in between Traversable and MonoTraversable?


I have a datatype and accompanying function that looks very much like some sort of traversal. Here’s a simplified example:

data Foo x = MkFoo (Bar x) (Bar x)

almostTraverse :: Applicative f => (Bar a -> f (Bar b)) -> Foo a -> f (Foo b)
almostTraverse f (MkFoo x y) = MkFoo <$> f x <*> f y

Assume that Bar is some opaque type, and isn’t necessarily a functor. Is there some typeclass that’s a generalization of almostTraverse? It’s not otraverse from MonoTraversable, because the result type inside the applicative doesn’t have to be exactly the same as the input type, and it’s not traverse from Traversable either, because the function passed in needs to be aware of the Bar despite it not being in the type parameter.


Solution

  • The lens package would call this a Traversal:

    almostTraverse :: Traversal (Foo a) (Foo b) (Bar a) (Bar b)
    

    You could consider making an instance of the Each typeclass, as in

    instance Each (Foo a) (Foo b) (Bar a) (Bar b) where
        each f (MkFoo x y) = liftA2 MkFoo (f x) (f y)