Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions Control/Parallel/Strategies.hs
Original file line number Diff line number Diff line change
Expand Up @@ -358,20 +358,24 @@ x `usingIO` strat = runEvalIO (strat x)
withStrategyIO :: Strategy a -> a -> IO a
withStrategyIO = flip usingIO

-- | Compose two strategies sequentially.
-- This is the analogue to function composition on strategies.
-- | Compose two strategies.
--
-- For any strategies @strat1@, @strat2@, and @strat3@,
-- > strat2 `dot` strat1 == strat2 . withStrategy strat1
--
-- 'dot' is associative:
--
-- > (strat1 `dot` strat2) `dot` strat3 == strat1 `dot` (strat2 `dot` strat3)
-- > strat1 `dot` strat1 = strat1
-- > strat1 `dot` r0 == strat1
--
-- > strat2 `dot` strat1 == strat2 . withStrategy strat1
-- 'r0' and 'rseq' are one-sided identities of 'dot':
--
-- > strat `dot` r0 == strat
-- > strat `dot` rseq == strat
{-# DEPRECATED dot "'dot' is an unintuitive composition operator. Use 'Control.Monad.<=<` instead." #-}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plus one for deprecating dot.

dot :: Strategy a -> Strategy a -> Strategy a
strat2 `dot` strat1 = strat2 . runEval . strat1

-- Note [dot proofs]
-- ~~~~~~~~~~~~~~~~~
-- Proof of strat2 `dot` strat1 == strat2 . withStrategy strat1
--
-- strat2 . withStrategy strat1
Expand All @@ -380,17 +384,14 @@ strat2 `dot` strat1 = strat2 . runEval . strat1
-- == \x -> strat2 (runEval (strat1 x))
-- == \x -> (strat2 . runEval . strat1) x
-- == strat2 `dot` strat1

-- One might be tempted to think that 'dot' is equivalent to '(<=<)',
-- the right-to-left Kleisli composition in the Eval monad, because
-- '(<=<)' can take the type @Strategy a -> Strategy a -> Strategy a@
-- and intuitively does what 'dot' does: First apply the strategy to the
-- right then the one to the left. However, there is a subtle difference
-- in strictness, witnessed by the following example:
--
-- > (r0 `dot` rseq) undefined == Done undefined
-- > (r0 <=< rseq) undefined == undefined
-- Proof of associativity
--
-- (strat1 `dot` strat2) `dot` strat3
-- == (strat1 . runEval . strat2) . runEval . strat3
-- == strat1 . runEval . strat2 . runEval . strat3
-- == strat1 . runEval . (strat2 . runEval . strat3)
-- == strat1 `dot` (strat2 `dot` strat3)

-- | Inject a sequential strategy (i.e., coerce a sequential strategy
-- to a general strategy).
Expand Down