async icon indicating copy to clipboard operation
async copied to clipboard

mapConcurrently / forConcurrently + lenses

Open Icelandjack opened this issue 7 years ago • 4 comments

async has some functions that can be parameterized by optics from lens, is this something that is worth adding.

mapConcurrently :: Traversable t => (a -> IO b) -> t a -> IO (t b)

forConcurrently :: Traversable t => t a -> (a -> IO b)-> IO (t b)

mapConcurrently_ :: Foldable f => (a -> IO b) -> f a -> IO ()

forConcurrently_ :: Foldable f => f a -> (a -> IO b) -> IO ()

can be parameterized by optics from lens

mapConcurrentlyOf :: LensLike Concurrently s t a b -> (a -> IO b) -> (s -> IO t)
mapConcurrentlyOf lens = flip (forConcurrentlyOf lens)

forConcurrentlyOf :: forall s t a b. LensLike Concurrently s t a b -> s -> (a -> IO b) -> IO t
forConcurrentlyOf = coerce (forOf @IO @s @t @a @b)

mapConcurrentlyOf_ :: forall s a r. Getting (Traversed r Concurrently) s a -> (a -> IO r) -> (s -> IO ())
mapConcurrentlyOf_ lens = flip (forConcurrentlyOf_ lens)

forConcurrentlyOf_ :: forall s a r. Getting (Traversed r Concurrently) s a -> s -> (a -> IO r) -> IO ()
forConcurrentlyOf_ = coerce (forOf_ @IO @r @s @a)

that run them concurrently

>> forConcurrentlyOf_ (replicated 10) 'a' print
'a''a''
'''aa'''a'
a''aaa'a'

'''
'

Icelandjack avatar Jan 04 '18 13:01 Icelandjack

I'm thinking that a much better solution is to create an optic modifier, something that takes lens-like over IO-like and produces LensLike Concurrently.

That way you can write

forConcurrentlyOf  lens = forOf  (asConcurrent lens)
forConcurrentlyOf_ lens = forOf_ (asConcurrent lens)

Icelandjack avatar Jan 04 '18 13:01 Icelandjack

I'm not a heavy lens user so I have no strong feelings on this, but I'd rather not take a dependency on lens. Can this be added in a separate async-lens package?

simonmar avatar Jan 08 '18 18:01 simonmar

@simonmar, lens defines

type LensLike f s t a b = (a -> f b) -> s -> f t

so mapConcurrentlyOf (which I'd call traverseConcurrentlyOf) and forConcurrentlyOf should be no problem. Traversed is a newtype defined in lens, and is frankly a bit of a mess, so I don't think the other two can be supported so easily.

treeowl avatar Mar 15 '23 03:03 treeowl

I'd rather not make async depend on lens. Could these be put into a separate package async-lens, say in a module Control.Concurrent.Async.Lens?

simonmar avatar Jun 08 '23 07:06 simonmar