RosettaCodeData/Task/Repeat/Python/repeat-2.py

100 lines
2.3 KiB
Python

'''Application of a given function, repeated N times'''
from itertools import repeat
from functools import reduce
from inspect import getsource
# applyN :: Int -> (a -> a) -> a -> a
def applyN(n):
'''n compounding applications of the supplied
function f. Equivalent to Church numeral n.
'''
def go(f):
return lambda x: reduce(
lambda a, g: g(a), repeat(f, n), x
)
return lambda f: go(f)
# MAIN ----------------------------------------------------
def main():
'''Tests - compounding repetition
of function application.
'''
def f(x):
return x + 'Example\n'
def g(x):
return 2 * x
def h(x):
return 1.05 * x
print(
fTable(__doc__ + ':')(
lambda fx: '\nRepeated * 3:\n (' + (
getsource(fst(fx)).strip() + ')(' +
repr(snd(fx)) + ')'
)
)(str)(
liftA2(applyN(3))(fst)(snd)
)([(f, '\n'), (g, 1), (h, 100)])
)
# GENERIC -------------------------------------------------
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
# fst :: (a, b) -> a
def fst(tpl):
'''First member of a pair.'''
return tpl[0]
# liftA2 :: (a0 -> b -> c) -> (a -> a0) -> (a -> b) -> a -> c
def liftA2(op):
'''Lift a binary function to a composition
over two other functions.
liftA2 (*) (+ 2) (+ 3) 7 == 90
'''
def go(f, g):
return lambda x: op(
f(x)
)(g(x))
return lambda f: lambda g: go(f, g)
# snd :: (a, b) -> b
def snd(tpl):
'''Second member of a pair.'''
return tpl[1]
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''
def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
# MAIN ---
if __name__ == '__main__':
main()