File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ from effect import Constant , Effect
2+
3+
4+ _sneaky = object ()
5+
6+ def fold_effect (f , initial , effects ):
7+ """
8+ Fold over effects.
9+
10+ The function will be called with the accumulator (starting with
11+ ``initial``) and a result of an effect repeatedly for each effect. The
12+ result of the previous call will be passed as the accumulator to the next
13+ call.
14+
15+ :param callable f: function of ``(accumulator, element) -> accumulator``
16+ :param initial: The value to be passed as the accumulator to the first
17+ invocation of ``f``.
18+ :param effects: sequence of Effects.
19+ """
20+
21+ def folder (acc , element ):
22+ # A bit of a hack here. We could just wrap `initial` in a
23+ # Effect(Constant()), but to simplify testing we avoid the additional
24+ # Effect by "sneaking" it in this way.
25+
26+ # This way people can use SequenceDispatcher and not get anything
27+ # unexpected.
28+ if acc is _sneaky :
29+ return element .on (lambda r : f (initial , r ))
30+ else :
31+ return acc .on (lambda r : element .on (lambda r2 : f (r , r2 )))
32+
33+ return reduce (folder , effects , _sneaky )
Original file line number Diff line number Diff line change 1+
2+ import operator
3+
4+ from effect import Constant , Effect , sync_perform
5+ from effect .fold import fold_effect
6+ from effect .testing import SequenceDispatcher
7+
8+
9+ def test_fold_effect ():
10+ effs = [Effect ('a' ), Effect ('b' ), Effect ('c' )]
11+
12+ dispatcher = SequenceDispatcher ([
13+ ('a' , lambda i : 'Ei' ),
14+ ('b' , lambda i : 'Bee' ),
15+ ('c' , lambda i : 'Cee' ),
16+ ])
17+ eff = fold_effect (operator .add , 'Nil' , effs )
18+
19+ with dispatcher .consume ():
20+ result = sync_perform (dispatcher , eff )
21+ assert result == 'NilEiBeeCee'
You can’t perform that action at this time.
0 commit comments