RosettaCodeData/Task/Loops-Increment-loop-index-.../Python/loops-increment-loop-index-...

149 lines
3.1 KiB
Python

'''Loops/Increment loop index within loop body.'''
from itertools import islice, takewhile
from functools import reduce
import operator
# main :: IO ()
def main():
'''Defines a list value, while printing a stream
of intermediate values during computation.
'''
gt = curry(operator.gt)
fst = operator.itemgetter(0)
list(takewhile(compose(gt(43), fst), series()))
# series :: (Int, Int) -> [(Int, Int)]
def series():
'''Non finite series, defined as a generator
with IO side-effects (to the print channel).
'''
def go(tpl):
if isPrime(tpl[1]):
# Side effect.
print(showTuple(tpl))
# Value.
return splitArrow(succ)(dbl)(tpl)
else:
return secondArrow(succ)(tpl)
return iterate(go)(
(1, 42)
)
# isPrime :: Int -> Bool
def isPrime(n):
'''True if n is prime.'''
if n in (2, 3):
return True
if 2 > n or 0 == n % 2:
return False
if 9 > n:
return True
if 0 == n % 3:
return False
def p(x):
return 0 == n % x or 0 == n % (2 + x)
return not any(map(p, range(5, 1 + int(n ** 0.5), 6)))
# showTuple :: (Int, Int) -> String
def showTuple(tpl):
'''Second integer shown with comma-chunked digits.'''
return '{:2} -> {:20,}'.format(*tpl)
# -------------------------GENERIC-------------------------
# compose :: ((a -> a), ...) -> (a -> a)
def compose(*fs):
'''Composition, from right to left,
of a series of functions.
'''
return lambda x: reduce(
lambda a, f: f(a),
fs[::-1], x
)
# curry :: ((a, b) -> c) -> a -> b -> c
def curry(f):
'''A curried function derived
from an uncurried function.
'''
return lambda x: lambda y: f(x, y)
# dbl :: Int -> Int -> Int
def dbl(x):
'''2 * x'''
return x + x
# drop :: Int -> [a] -> [a]
# drop :: Int -> String -> String
def drop(n):
'''The sublist of xs beginning at
(zero-based) index n.
'''
def go(xs):
take(n)(xs)
return xs
return go
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
v = x
while True:
yield v
v = f(v)
return go
# secondArrow :: (b -> c) -> (a, b...) -> (a, c ...)
def secondArrow(f):
'''A simple function lifted to one which applies
to a tuple, transforming only its second value.
'''
return lambda tpl: (tpl[0], f(tpl[1]))
# splitArrow (***) :: (a -> b) -> (c -> d) -> ((a, c) -> (b, d))
def splitArrow(f):
'''A function from (x, y) to a tuple of (f(x), g(y))
'''
return lambda g: lambda tpl: (f(tpl[0]), g(tpl[1]))
# succ :: Enum a => a -> a
def succ(x):
'''The successor of a value.
For numeric types, (1 +).
'''
return 1 + x
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.
'''
return lambda xs: list(islice(xs, n))
# MAIN ---
if __name__ == '__main__':
main()