Skip to content

Commit 3077f53

Browse files
committed
commit some functional code
1 parent 90cc106 commit 3077f53

2 files changed

Lines changed: 101 additions & 0 deletions

File tree

functional/func_tools.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import inspect
2+
import operator
3+
from functools import reduce, partial
4+
5+
def identity(x):
6+
return x
7+
8+
def apply(*func_and_args, **kwargs):
9+
if not func_and_args:
10+
raise TypeError('function argument is required.')
11+
func, args = func_and_args[0], func_and_args[1:]
12+
return func(*args, **kwargs)
13+
14+
def thread_first(val, *forms):
15+
def evalform_front(val, form):
16+
if callable(form):
17+
return form(val)
18+
if isinstance(form, tuple):
19+
func, args = form[0], form[1:]
20+
args = (val,) + args
21+
return func(*args)
22+
return reduce(evalform_back, forms, val)
23+
24+
class curry(object):
25+
def __init__(self, *args, **kwargs):
26+
if not args:
27+
raise TypeError('__init__() takes at least 2 arguments (1 given)')
28+
func, args = args[0], args[1:]
29+
if not callable(func):
30+
raise TypeError("Input must be callable")
31+
32+
if (
33+
hasattr(func, 'func')
34+
and hasattr(func, 'args')
35+
and hasattr(func, 'keywords')
36+
and isinstance(func.args, tuple)
37+
):
38+
_kwargs = {}
39+
if func.keywords:
40+
_kwargs.update(func.keywords)
41+
_kwargs.update(kwargs)
42+
kwargs = _kwargs
43+
args = func.args + args
44+
func = func.func
45+
46+
if kwargs:
47+
self._partial = partial(func, *args, **kwargs)
48+
else:
49+
self._partial = partial(func, *args)
50+
51+
52+

pymonad/monad.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from typing import Callable, Generic, TypeVar, Union
2+
3+
S = TypeVar('S')
4+
T = TypeVar('T')
5+
6+
class Monad(Generic[T]):
7+
def __init__(self, value, monoid):
8+
self.value = value
9+
self.monoid = monoid
10+
11+
@classmethod
12+
def apply(cls, function):
13+
class _Application(cls):
14+
amap = cls.amap
15+
bind = cls.bind
16+
insert = cls.insert
17+
map = cls.map
18+
@staticmethod
19+
def to_arguments(*args):
20+
results = cls.insert(function)
21+
for arg in args:
22+
results = result.amap(arg)
23+
return cls(result.value, result.monoid)
24+
return _Application(None, None)
25+
26+
@classmethod
27+
def insert(cls, value: T) -> 'Monad[T]':
28+
raise NotImplementedError
29+
30+
def amap(self: 'Monad[Callable[[S], T]]', monad_value: 'Monad[S]') -> 'Monad[T]':
31+
return monad_value.map(self.value)
32+
33+
def bind(self: 'Monad[S]', kleisli_function: Callable[[S], 'Monad[T]']) -> 'Monad[T]':
34+
raise NotImplementedError
35+
36+
def map(self: 'Monad[S]', function: Callable[[S], T]) -> 'Monad[T]':
37+
raise NotImplementedError("'fmap' not defined.")
38+
39+
def then(
40+
self: 'Monad[S]', function: Union[Callable[[S], T], Callable[[S], 'Monad[T]']]
41+
) -> 'Monad[T]':
42+
try:
43+
result = self.bind(function)
44+
if isinstance(result, Monad):
45+
return result
46+
else:
47+
return self.map(function)
48+
except AttributeError:
49+
return self.map(function)

0 commit comments

Comments
 (0)