{-# LANGUAGE Arrows #-} foo f g h ma = proc ( (a, b), (c, d), (e, f) ) -> do -- Begin do (x,y) -- GHC parser fails if layed out over multiple lines <- f -- Call into f (a, c) -- Tuple together arguments (b, d) -< (b + 1, -- Funnel into arrow d * b) if x `mod` y == 0 -- Basic condition then case e -- Only left case is relevant of Left (z, w) -> \u -> -- Procs can have lambdas let v = u -- Actually never used ^ 2 in (returnA -< -- Just do the calculation (x + y * z)) else do let u = x -- Let bindings bind expressions, not commands -- Could pattern match directly on x i <- case u of 0 -> (g . h -< u) n -> ( (h . g -< y) -- First actual use of y ) returnA -< () -- Sometimes execute effects if i > 0 then ma -< () else returnA -< () returnA -< (i + x * y) -- Just do the calculation