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.

Upvotes: 3

Views: 141

Answers (1)

Daniel Wagner
Daniel Wagner

Reputation: 153172

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)

Upvotes: 6

Related Questions