{"id":20629596,"url":"https://github.com/threecifanggen/python-functional-programming","last_synced_at":"2025-04-15T18:18:14.422Z","repository":{"id":45147642,"uuid":"301311020","full_name":"threecifanggen/python-functional-programming","owner":"threecifanggen","description":"Functional Programming Learning in Python.","archived":false,"fork":false,"pushed_at":"2022-12-17T07:43:48.000Z","size":364,"stargazers_count":16,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T23:21:17.580Z","etag":null,"topics":["functional-programming","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/threecifanggen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-10-05T06:16:50.000Z","updated_at":"2024-11-05T02:51:29.000Z","dependencies_parsed_at":"2023-01-29T17:00:39.575Z","dependency_job_id":null,"html_url":"https://github.com/threecifanggen/python-functional-programming","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threecifanggen%2Fpython-functional-programming","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threecifanggen%2Fpython-functional-programming/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threecifanggen%2Fpython-functional-programming/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threecifanggen%2Fpython-functional-programming/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/threecifanggen","download_url":"https://codeload.github.com/threecifanggen/python-functional-programming/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248809026,"owners_count":21164895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-programming","python"],"created_at":"2024-11-16T14:05:25.898Z","updated_at":"2025-04-15T18:18:14.401Z","avatar_url":"https://github.com/threecifanggen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fppy\n\n开发状态：\n\n![coverage](badge/cov-badge.svg) ![open-issues](https://img.shields.io/github/issues/threecifanggen/python-functional-programming) ![close-issues](https://img.shields.io/github/issues-closed/threecifanggen/python-functional-programming) ![version](https://img.shields.io/github/v/release/threecifanggen/python-functional-programming?include_prereleases) ![building](https://img.shields.io/github/workflow/status/threecifanggen/python-functional-programming/Publish%20fppy-learn%20to%20PYPI)\n\n依赖：\n\n![Python](https://img.shields.io/badge/Python-3.10-green?logo=python) ![Python](https://img.shields.io/badge/pathos-0.2.6-green) ![Python](https://img.shields.io/badge/drill-1.2.0-green)\n\n一个基于`python`的函数式编程类库，仅做学习使用。主要功能如下：\n\n- [x] 常量定义\n- [x] 惰性求值/惰性属性\n- [x] 抽象代数\n- [x] 常用组合子\n- [x] 列表类\n  - [x] 基于`Iterable`的惰性列表\n  - [x] 基于元组定义的列表\n  - [x] 基于类定义的列表\n  - [x] 基于类从头定义的惰性列表 \n- [x] 偏函数\n- [x] 基于性质测试(Property-based Testing)\n- [x] 更多功能的函数装饰器\n- [ ] State类\n- [ ] 设计模式\n  - [ ] 错误处理\n    - [x] Option类\n    - [x] Either类\n    - [x] Try类\n  - [ ] Lens\n  - [ ] Cake\n\n## 如何安装\n\n从[PYPI](https://pypi.org/)软件库：\n\n```bash\npip install fppy-learn\n```\n\n下载源码自己安装：\n\n```python\npip install poetry\n\ngit clone https://github.com/threecifanggen/python-functional-programming.git\ncd python-functional-programming\n\npoetry install\n```\n\n## 快速功能预览\n\n### 函数修饰器\n\n```python\nfrom fppy.base import F_\n\n@F_\ndef f(x):\n    return x + 1\n\n\u003e\u003e\u003e f(1)\n2\n\u003e\u003e\u003e f.apply(1)\n2\n\u003e\u003e\u003e f.and_then(lambda x: x ** 3)(1) # (x + 1) ** 3\n8\n\u003e\u003e\u003e f.compose(lambda x: x ** 3)(1) # (x ** 3) + 1\n1\n\u003e\u003e\u003e f.map([1, 2, 3])\n[2, 3, 4]\n```\n\n### 常量定义\n\n```python\n\u003e\u003e\u003e from fppy.const import Const\n\u003e\u003e\u003e\n\u003e\u003e\u003e const = Const()\n\u003e\u003e\u003e const.a = 1\n\u003e\u003e\u003e const.a\n1\n\u003e\u003e\u003e const.a = 2\n# raise ConstError\n```\n\n### 列表类\n\n一个可以实现`map`、`reduce`等操作的惰性列表\n\n#### 元组实现的列表\n\n##### 1. 新建\n\n```python\nfrom fppy.cons_list_base import *\n\na = cons_apply(1, 2, 3)\nhead(a) # 1\ntail(a) # cons(2, cons(3, ()))\n```\n\n##### 2. 打印\n\n```python\n\u003e\u003e\u003e print_cons(cons_apply(1, 2, 3))\n1, 2, 3, nil\n```\n\n##### 3. 列表操作\n\n```python\na = cons_apply(1, 2, 3)\nmap_cons_curry(lambda x: x + 1)(a) # cons_apply(2, 3, 4)\nfilter_cons_curry(lambda x: x % 2 == 0)(a) # cons_apply(2)\nfold_left_cons_curry(lambda x, y: x + y)(0)(a) # 6\n```\n\n#### 类实现的列表\n\n```python\nfrom fppy.cons_list import Cons\n\nCons.maker(1, 2, 3)\\\n    .map(lambda x: x + 1)\\\n    .filter(lambda x: x % 2 == 0)\\\n    .fold_left(lambda x, y: x + y, 0)\n```\n\n#### 从头实现的惰性列表\n\n```python\nfrom fppy.lazy_list_base import LazyCons\n\nLazyCons.from_iter(1)(lambda x: x)\\\n    .map(lambda x: x + 1)\\\n    .filter(lambda x: x % 2 == 0)\\\n    .take(3)\\\n    .fold_left(lambda x, y: x + y, 0)\n```\n\n#### 惰性列表\n\n##### 1. 新建\n\n```python\nfrom fppy.lazy_list import LazyList\n\n# 定义正整数无穷列表\nll = LazyList.from_iter(2)(lambda x: x + 2)\n\n# 从List对象定义\nll = LazyList([1, 2, 3])\n\n# 从生成器、迭代器定义\nx = (i for i in range(100))\nll = LazyList(x)\n```\n\n##### 2. map、filter、collect\n\n```python\nLazyList([1, 2, 3])\\\n    .map(lambda x: x + 1)\\\n    .filter(lambda x: x % 2 == 0)\\\n    .collect() # 返回[2, 4]\n```\n\n##### 3. 其他\n\n其他方法参考文档。\n\n### 常见组合子\n\n#### 1. Y组合子\n\n下面的例子是计算阶乘：\n\n```python\nfrom fppy.combinator import Y\n\nfac = Y(lambd f: lambda x: 1 if (x ==0) else x * f(x - 1))\n```\n\n#### 2. Z组合子\n\n下面是计算指数函数的Z组合子实现\n\n```python\nfrom fppy.combinator import Z\n\npower = Z(lambda f: lambda x, n: 1 if (n == 0) else x * f(x, n - 1))\n```\n\n### 偏函数\n\n这里的偏函数是指Partial Function，即定义域取不完整的函数；而不是高阶函数中的Partial Applied Function的概念。\n\n定义一个如下函数：\n\n- 如果`x \u003e 0`，则计算`1 / x`\n- 如果`x \u003c 0`，则计算`log(-x)`\n\n```python\nfrom math import log\nfrom fppy.partail_function import PartialFunction\n# 直接定义\npf = PartialFunction\\\n    .case(lambda x: x \u003e 0)\\\n    .then(lambda x: 1 / x)\\\n    .case(lambda x: x \u003c 0)\\\n    .then(lambda x: log(-x))\n\n## 计算\npf.apply(1) # 返回1\npf.apply(-1) # 返回0\npf.apply(0) # 返回NoOtherCaseError\n\n## 判断是否在某点有定义\npf.is_defined_at(0.4) # 返回True\npf.is_defined_at(0) # 返回False\n```\n\n我们还可以使用`or_else`来组合偏函数，比如上面的函数可以如下实现：\n\n```python\npf_greater_then_0 = PartialFunction\\\n    .case(lambda x: x \u003e 0)\\\n    .then(lambda x: 1 / x)\n\npf_less_then_0 = PartialFunction\\\n    .case(lambda x: x \u003c 0)\\\n    .then(lambda x: log(-x))\n\npf = pf_greater_then_0.or_else(pf_less_then_0)\n```\n\n### 惰性求值\n\n#### 1. 惰性属性\n\n```python\nfrom fppy.lazy_evaluate import lazy_property\n\n@dataclass\nclass Circle:\n    x: float\n    y: float\n    r: float\n\n    @lazy_property\n    def area(self):\n        print(\"area compute\")\n        return self.r ** 2 * 3.14\n```\n\n以上定义了一个圆的类，具体获取`area`时，仅第一次会计算（通过打印`\"area compute\"`显示）。\n\n#### 2. 惰性值\n\n`Python`没有代码块的概念，所以必须把惰性求值过程包在一个函数内，以下是调用方法：\n\n```python\nfrom fppy.lazy_evaluate import lazy_val\n\ndef f():\n    print(\"f compute\")\n    return 12\n\nlazy_val.a = f\n```\n\n调用结果下：\n\n```python\n\u003e\u003e\u003e lazy_val.a\nf compute\n12\n\u003e\u003e\u003e lazy_val.a\n12\n```\n\n这就表示仅第一次调用时发生了计算。\n\n### 错误处理\n\n### 1. Option\n\n```python\nfrom fppy.option import Just, Nothing\n\n\u003e\u003e\u003e Just(1).map(lambda x: x + 1)\nJust(2)\n\u003e\u003e\u003e Just(1).flat_map(lambda x: Just(x * 3))\nJust(3)\n\u003e\u003e\u003e Just(1).get\n1\n\u003e\u003e\u003e Just(1).get_or_else(2)\n1\n\u003e\u003e\u003e Just(1).filter(lambda x: x \u003c 0)\nNothing()\n\u003e\u003e\u003e Just(1).filter(lambda x: x \u003e 0)\nJust(1)\n```\n\n与偏函数合用会有很多妙处：\n\n```python\nfrom math import log\nfrom fppy.partail_function import PartialFunction\n\npf = PartialFunction\\\n    .case(lambda x: x \u003e 0)\\\n    .then(lambda x: 1 / x)\\\n    .case(lambda x: x \u003c 0)\\\n    .then(lambda x: log(-x))\n\n\n\u003e\u003e\u003e pf.lift(1)\nJust(1)\n\u003e\u003e\u003e pf.lift(0)\nNothing()\n\u003e\u003e\u003e Just(1).collect(pf)\nJust(1)\n\u003e\u003e\u003e Just(0).collect(pf)\nNothing()\n\n\u003e\u003e\u003e Just(1).collect(pf)\nJust(1.)\n\u003e\u003e\u003e Just(1).collect(pf).map(lambda x: int(x) - 1)\nJust(-1)\n\u003e\u003e\u003e Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf)\nJust(0)\n\u003e\u003e\u003e Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf).collect(pf)\nNothing()\n\u003e\u003e\u003e Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf).collect(pf).collect(pf)\nNothing()\n\u003e\u003e\u003e Just(1).collect(pf).map(lambda x: int(x) - 1).collect(pf).collect(pf).collect(pf).get_or_else(2)\n2\n\n```\n\n### 2. Either\n\n(待完善)\n\n### 3. Try\n\n`Try`单子时一个非常方便地处理错误的类，它的逻辑时传递错误类一直到最后处理，可以获取到错误发生时的错误类型和输入值，方便调试：\n\n```python\n\u003e\u003e\u003e from fppy.try_monad import Try\n\u003e\u003e\u003e res = Try(1).map(lambda x: x / 0).map(lambda x: x + 1)\n\u003e\u003e\u003e res.error\nZeroDivisionError('division by zero')\n\u003e\u003e\u003e res.get_or_else(2)\n2\n\u003e\u003e\u003e res.get_error_input()\n1\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreecifanggen%2Fpython-functional-programming","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthreecifanggen%2Fpython-functional-programming","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreecifanggen%2Fpython-functional-programming/lists"}