A implements of Functional Programming in Python.
Project description
fppy
开发状态:
依赖:
一个基于python的函数式编程类库,仅做学习使用。主要功能如下:
- 常量定义
- 惰性求值/惰性属性
- 抽象代数
- 常用组合子
- 列表类
- 基于
Iterable的惰性列表 - 基于元组定义的列表
- 基于类定义的列表
- 基于类从头定义的惰性列表
- 基于
- 偏函数
- 基于性质测试(Property-based Testing)
- 更多功能的函数装饰器
- State类
- 设计模式
- 错误处理
- Option类
- Either类
- Try类
- Lens
- Cake
- 错误处理
如何安装
从PYPI软件库:
pip install fppy-learn
下载源码自己安装:
pip install poetry
git clone https://github.com/threecifanggen/python-functional-programming.git
cd python-functional-programming
poetry install
快速功能预览
函数修饰器
from fppy.base import F_
@F_
def f(x):
return x + 1
>>> f(1)
2
>>> f.apply(1)
2
>>> f.and_then(lambda x: x ** 3)(1) # (x + 1) ** 3
8
>>> f.compose(lambda x: x ** 3)(1) # (x ** 3) + 1
1
>>> f.map([1, 2, 3])
[2, 3, 4]
常量定义
>>> from fppy.const import Const
>>>
>>> const = Const()
>>> const.a = 1
>>> const.a
1
>>> const.a = 2
# raise ConstError
列表类
一个可以实现map、reduce等操作的惰性列表
元组实现的列表
1. 新建
from fppy.cons_list_base import *
a = cons_apply(1, 2, 3)
head(a) # 1
tail(a) # cons(2, cons(3, ()))
2. 打印
>>> print_cons(cons_apply(1, 2, 3))
1, 2, 3, nil
3. 列表操作
a = cons_apply(1, 2, 3)
map_cons_curry(lambda x: x + 1)(a) # cons_apply(2, 3, 4)
filter_cons_curry(lambda x: x % 2 == 0)(a) # cons_apply(2)
fold_left_cons_curry(lambda x, y: x + y)(0)(a) # 6
类实现的列表
from fppy.cons_list import Cons
Cons.maker(1, 2, 3)\
.map(lambda x: x + 1)\
.filter(lambda x: x % 2 == 0)\
.fold_left(lambda x, y: x + y, 0)
从头实现的惰性列表
from fppy.lazy_list_base import LazyCons
LazyCons.from_iter(1)(lambda x: x)\
.map(lambda x: x + 1)\
.filter(lambda x: x % 2 == 0)\
.take(3)\
.fold_left(lambda x, y: x + y, 0)
惰性列表
1. 新建
from fppy.lazy_list import LazyList
# 定义正整数无穷列表
ll = LazyList.from_iter(2)(lambda x: x + 2)
# 从List对象定义
ll = LazyList([1, 2, 3])
# 从生成器、迭代器定义
x = (i for i in range(100))
ll = LazyList(x)
2. map、filter、collect
LazyList([1, 2, 3])\
.map(lambda x: x + 1)\
.filter(lambda x: x % 2 == 0)\
.collect() # 返回[2, 4]
3. 其他
其他方法参考文档。
常见组合子
1. Y组合子
下面的例子是计算阶乘:
from fppy.combinator import Y
fac = Y(lambd f: lambda x: 1 if (x ==0) else x * f(x - 1))
2. Z组合子
下面是计算指数函数的Z组合子实现
from fppy.combinator import Z
power = Z(lambda f: lambda x, n: 1 if (n == 0) else x * f(x, n - 1))
偏函数
这里的偏函数是指Partial Function,即定义域取不完整的函数;而不是高阶函数中的Partial Applied Function的概念。
定义一个如下函数:
- 如果
x > 0,则计算1 / x - 如果
x < 0,则计算log(-x)
from math import log
from fppy.partail_function import PartialFunction
# 直接定义
pf = PartialFunction\
.case(lambda x: x > 0)\
.then(lambda x: 1 / x)\
.case(lambda x: x < 0)\
.then(lambda x: log(-x))
## 计算
pf.apply(1) # 返回1
pf.apply(-1) # 返回0
pf.apply(0) # 返回NoOtherCaseError
## 判断是否在某点有定义
pf.is_defined_at(0.4) # 返回True
pf.is_defined_at(0) # 返回False
我们还可以使用or_else来组合偏函数,比如上面的函数可以如下实现:
pf_greater_then_0 = PartialFunction\
.case(lambda x: x > 0)\
.then(lambda x: 1 / x)
pf_less_then_0 = PartialFunction\
.case(lambda x: x < 0)\
.then(lambda x: log(-x))
pf = pf_greater_then_0.or_else(pf_less_then_0)
惰性求值
1. 惰性属性
from fppy.lazy_evaluate import lazy_property
@dataclass
class Circle:
x: float
y: float
r: float
@lazy_property
def area(self):
print("area compute")
return self.r ** 2 * 3.14
以上定义了一个圆的类,具体获取area时,仅第一次会计算(通过打印"area compute"显示)。
2. 惰性值
Python没有代码块的概念,所以必须把惰性求值过程包在一个函数内,以下是调用方法:
from fppy.lazy_evaluate import lazy_val
def f():
print("f compute")
return 12
lazy_val.a = f
调用结果下:
>>> lazy_val.a
f compute
12
>>> lazy_val.a
12
这就表示仅第一次调用时发生了计算。
错误处理
1. Option
from fppy.option import Just, Nothing
>>> Just(1).map(lambda x: x + 1)
Just(2)
>>> Just(1).flat_map(lambda x: Just(x * 3))
Just(3)
>>> Just(1).get
1
>>> Just(1).get_or_else(2)
1
>>> Just(1).filter(lambda x: x < 0)
Nothing()
>>> Just(1).filter(lambda x: x > 0)
Just(1)
与偏函数合用会有很多妙处:
from math import log
from fppy.partail_function import PartialFunction
pf = PartialFunction\
.case(lambda x: x > 0)\
.then(lambda x: 1 / x)\
.case(lambda x: x < 0)\
.then(lambda x: log(-x))
>>> pf.lift(1)
Just(1)
>>> pf.lift(0)
Nothing()
>>> Just(1).collect(pf)
Just(1)
>>> Just(0).collect(pf)
Nothing()
>>> Just(1).collect(pf)
Just(1.)
>>> Just(1).collect(pf).map(lambda x: int(x) - 1)
Just(-1)
>>> Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf)
Just(0)
>>> Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf).collect(pf)
Nothing()
>>> Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf).collect(pf).collect(pf)
Nothing()
>>> Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf).collect(pf).collect(pf).get_or_else(2)
2
2. Either
(待完善)
3. Try
Try单子时一个非常方便地处理错误的类,它的逻辑时传递错误类一直到最后处理,可以获取到错误发生时的错误类型和输入值,方便调试:
>>> from fppy.try_monad import Try
>>> res = Try(1).map(lambda x: x / 0).map(lambda x: x + 1)
>>> res.error
ZeroDivisionError('division by zero')
>>> res.get_or_else(2)
2
>>> res.get_error_input()
1
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fppy-learn-0.2.0.post220105.tar.gz.
File metadata
- Download URL: fppy-learn-0.2.0.post220105.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.12 CPython/3.10.0 Windows/10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4b7ad271944f75929f06692f6f3b7fed229e0eb29f7bef6b94234d7ad140dc0
|
|
| MD5 |
642ace22b7fd261d28334887b4c3f735
|
|
| BLAKE2b-256 |
8ebac76793e075ba156ec378b899748d78471bd812943ce4391521e324fea2cc
|
File details
Details for the file fppy_learn-0.2.0.post220105-py3-none-any.whl.
File metadata
- Download URL: fppy_learn-0.2.0.post220105-py3-none-any.whl
- Upload date:
- Size: 24.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.12 CPython/3.10.0 Windows/10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30d4764b51e6f01823d95673ad4729fd4ec8112f00618b716c73c7f0e7e70421
|
|
| MD5 |
beb00a0d042f6ec3e9e870eb57e8394d
|
|
| BLAKE2b-256 |
491353b397c8f038b320fa3a22abf8dff5eeb1ab986f5f4be9eea26838b25e24
|