Actions¶
monad.actions - useful monadic actions.
-
monad.actions.
either
(left_handler, right_handler=identity)[source]¶ Case analysis for
Either
.Returns a function that when called with a value of type
Either
, applies eitherleft_handler
orright_handler
to that value depending on the type of it. If an incompatible value is passed, aTypeError
will be raised.>>> def log(v): ... print('Got Left({})'.format(v)) >>> logger = either(left_handler=log) >>> logger(Left(1)) Got Left(1) >>> logger(Right(1)) 1 >>> def inc(v): ... return v + 1 >>> act = either(log, inc) >>> [act(v) for v in (Left(0), Right(1), Left(2), Right(3))] Got Left(0) Got Left(2) [None, 2, None, 4]
-
monad.actions.
first
(sequence, default=Nothing, predicate=None)[source]¶ Iterate over a sequence, return the first
Just
.If
predicate
is provided,first
returns the first item that satisfy thepredicate
, the item will be wrapped in aJust
if it is not already, so that the return value of this function will be an instance ofMaybe
in all circumstances. Returnsdefault
if no satisfied value in the sequence,default
defaults toNothing
.>>> from monad.types import Just, Nothing >>> first([Nothing, Nothing, Just(42), Nothing]) Just(42) >>> first([Just(42), Just(43)]) Just(42) >>> first([Nothing, Nothing, Nothing]) Nothing >>> first([]) Nothing >>> first([Nothing, Nothing], default=Just(2)) Just(2) >>> first([False, 0, True], predicate=bool) Just(True) >>> first([False, 0, Just(1)], predicate=bool) Just(1) >>> first([False, 0, ''], predicate=bool) Nothing >>> first(range(100), predicate=lambda x: x > 40 and x % 2 == 0) Just(42) >>> first(range(100), predicate=lambda x: x > 100) Nothing
This is basically a customized version of
msum
forMaybe
, a separate function like this is needed because there is no way to write a genericmsum
in python that cab be evaluated in a non-strict way. The obviousreduce(operator.add, sequence)
, albeit beautiful, is strict, unless we build up the sequence with generator expressions in-place.Maybe (pun intended!) implemented as
MonadOr
instead ofMonadPlus
might be more semantically correct in this case.
-
monad.actions.
tryout
(*functions)[source]¶ Combine functions into one.
Returns a monadic function that when called, will try out functions in
functions
one by one in order, testing the result, stop and return with the first value that is true or the last result.>>> zero = lambda n: 'zero' if n == 0 else False >>> odd = lambda n: 'odd' if n % 2 else False >>> even = lambda n: 'even' if n % 2 == 0 else False >>> test = tryout(zero, odd, even) >>> test(0) 'zero' >>> test(1) 'odd' >>> test(2) 'even'