Last active
          July 22, 2022 13:34 
        
      - 
      
- 
        Save pete-murphy/5f5fb60e3e30b8ea0a3092e3cb1e37ee to your computer and use it in GitHub Desktop. 
    Parallel traverse with V and Compose
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | module Main where | |
| import Prelude | |
| import Control.Monad.Except (ExceptT(..)) | |
| import Control.Monad.Except as Except | |
| import Control.Monad.Except as ExceptT | |
| import Control.Parallel as Parallel | |
| import Control.Parallel (class Parallel) | |
| import Data.Array ((..)) | |
| import Data.Array.NonEmpty (NonEmptyArray) | |
| import Data.Array.NonEmpty as NonEmpty | |
| import Data.Bifunctor as Bifunctor | |
| import Data.Functor.Compose (Compose(..)) | |
| import Data.Newtype as Newtype | |
| import Data.Time.Duration (Milliseconds(..)) | |
| import Data.Traversable (class Traversable) | |
| import Data.Traversable as Traversable | |
| import Data.Validation.Semigroup (V(..)) | |
| import Data.Validation.Semigroup as V | |
| import Effect (Effect) | |
| import Effect.Aff (Aff, ParAff) | |
| import Effect.Aff as Aff | |
| import Effect.Aff.Class (class MonadAff) | |
| import Effect.Aff.Class as Aff.Class | |
| import Effect.Class.Console as Console | |
| delaySeconds :: forall m. MonadAff m => Number -> m Unit | |
| delaySeconds n = Aff.Class.liftAff do | |
| Aff.delay (Milliseconds (n * 1000.0)) | |
| delayedThrow :: Int -> ExceptT Int Aff Unit | |
| delayedThrow err = do | |
| delaySeconds 1.0 | |
| Console.logShow err | |
| Except.throwError err | |
| -- traverseV | |
| -- :: forall t a b err | |
| -- . Traversable t | |
| -- => (a -> ExceptT err Aff b) | |
| -- -> t a | |
| -- -> ExceptT (NonEmptyArray err) Aff (t b) | |
| traverseV | |
| :: forall f m t a b err | |
| . Traversable t | |
| => Parallel f m | |
| => (a -> ExceptT err m b) | |
| -> t a | |
| -> ExceptT (NonEmptyArray err) m (t b) | |
| traverseV f = ExceptT | |
| <<< Parallel.sequential | |
| <<< map V.toEither | |
| <<< Newtype.unwrap | |
| <<< Traversable.traverse (toComposeV <<< f) | |
| where | |
| toComposeV :: ExceptT err m b -> Compose f (V (NonEmptyArray err)) b | |
| toComposeV = | |
| Compose | |
| <<< Parallel.parallel | |
| <<< map (V <<< Bifunctor.lmap (NonEmpty.singleton)) | |
| <<< ExceptT.runExceptT | |
| main :: Effect Unit | |
| main = do | |
| let xs = 1 .. 10 | |
| Console.time "parTraverse" | |
| Aff.runAff_ (\result -> Console.timeEnd "parTraverse" *> Console.logShow result) do | |
| ExceptT.runExceptT (Parallel.parTraverse delayedThrow xs) | |
| Console.time "traverseV" | |
| Aff.runAff_ (\result -> Console.timeEnd "traverseV" *> Console.logShow result) do | |
| ExceptT.runExceptT (traverseV delayedThrow xs) | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment