Skip to content

Commit 88ccea0

Browse files
committed
Fix dot documentation
1 parent 58af4f0 commit 88ccea0

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

Control/Parallel/Strategies.hs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -359,19 +359,30 @@ withStrategyIO :: Strategy a -> a -> IO a
359359
withStrategyIO = flip usingIO
360360

361361
-- | Compose two strategies sequentially.
362-
-- This is the analogue to function composition on strategies.
363362
--
364-
-- For any strategies @strat1@, @strat2@, and @strat3@,
363+
-- > strat2 `dot` strat1 == strat2 . withStrategy strat1
364+
--
365+
-- 'dot' is associative:
365366
--
366367
-- > (strat1 `dot` strat2) `dot` strat3 == strat1 `dot` (strat2 `dot` strat3)
367-
-- > strat1 `dot` strat1 = strat1
368-
-- > strat1 `dot` r0 == strat1
369368
--
370-
-- > strat2 `dot` strat1 == strat2 . withStrategy strat1
369+
-- 'r0' and 'rseq' are one-sided identities of 'dot':
370+
--
371+
-- > strat `dot` r0 == strat
372+
-- > strat `dot` rseq == strat
371373
--
374+
-- Furthermore, since strategies should only force and spark computations
375+
-- (that is, they don't actually change any values),
376+
--
377+
-- > strat `dot` strat == strat
378+
--
379+
-- Perhaps unexpectedly, @r0 `dot` strat == r0@.
380+
-- 'Control.Monad.<=<' has a more intuitive behaviour (@r0 <=< strat == strat@).
372381
dot :: Strategy a -> Strategy a -> Strategy a
373382
strat2 `dot` strat1 = strat2 . runEval . strat1
374383

384+
-- Note [dot proofs]
385+
-- ~~~~~~~~~~~~~~~~~
375386
-- Proof of strat2 `dot` strat1 == strat2 . withStrategy strat1
376387
--
377388
-- strat2 . withStrategy strat1
@@ -380,17 +391,14 @@ strat2 `dot` strat1 = strat2 . runEval . strat1
380391
-- == \x -> strat2 (runEval (strat1 x))
381392
-- == \x -> (strat2 . runEval . strat1) x
382393
-- == strat2 `dot` strat1
383-
384-
-- One might be tempted to think that 'dot' is equivalent to '(<=<)',
385-
-- the right-to-left Kleisli composition in the Eval monad, because
386-
-- '(<=<)' can take the type @Strategy a -> Strategy a -> Strategy a@
387-
-- and intuitively does what 'dot' does: First apply the strategy to the
388-
-- right then the one to the left. However, there is a subtle difference
389-
-- in strictness, witnessed by the following example:
390394
--
391-
-- > (r0 `dot` rseq) undefined == Done undefined
392-
-- > (r0 <=< rseq) undefined == undefined
395+
-- Proof of associativity
393396
--
397+
-- (strat1 `dot` strat2) `dot` strat3
398+
-- == (strat1 . runEval . strat2) . runEval . strat3
399+
-- == strat1 . runEval . strat2 . runEval . strat3
400+
-- == strat1 . runEval . (strat2 . runEval . strat3)
401+
-- == strat1 `dot` (strat2 `dot` strat3)
394402

395403
-- | Inject a sequential strategy (i.e., coerce a sequential strategy
396404
-- to a general strategy).

0 commit comments

Comments
 (0)