-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecorators.py
98 lines (80 loc) · 2.19 KB
/
decorators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from funcs import *
# Create an anonymous function applying the function given
# Curry it so we can take in the current state and wrap it
# around the function taken in
def craft(fun):
return lambda s: lambda x: s(fun(x))
# Classic ID function
def _id(f):
return craft(f)(lambda x: x)
# Logging function to output the current state
# Note that if functions have multiple logs in
# their chains, we will get weird-looking log messages
def _puts(f):
def inner(x):
data = f(x)
print("Current state is {}".format(data))
return data
return inner
# Numeric functions (add1/sub1 from racket)
def _add1(f):
return craft(f)(add1)
def _sub1(f):
return craft(f)(sub1)
# Head and tail of lists
def _head(f):
return craft(f)(head)
def _tail(f):
return craft(f)(tail)
# Create a list using range(x)
def _range(f):
return craft(f)(range)
# Creates a range of nums from x to y inclusive
def _to(y):
def wrap(f):
def inner(x):
return range(f(x), y+1)
return inner
return wrap
# Enumerate a list of items [(0,a), (1,b), ...]
def _enum(f):
return craft(f)(enumerate)
# Apply an any() to the object
def _any(f):
return craft(f)(any)
# Apply an all() to the object
def _all(f):
return craft(f)(all)
# Apply a list function to the result (useful for Python3)
# Functions in Py3 return generators as opposed to raw lists
def _list(f):
return craft(f)(list)
# Functor mapping - only functor is List thus far
def _fmap(func):
def wrap(f):
def inner(x):
return list(map(func, f(x)))
return inner
return wrap
# Filter - apply a filter over an iterable
def _filter(func):
def wrap(f):
def inner(x):
return list(filter(func, f(x)))
return inner
return wrap
# Fold-left over an iterable of items
# Should only work when a list contains only one type
def _foldl(func):
def wrap(f):
def inner(x):
res = f(x) # store the results so we don't apply f twice
z = head(res)
for y in tail(res):
z = func(z, y)
return z
return inner
return wrap
# end