易于使用的功能工具:(de)组合与类型检查(curry,箭头),多重分派
lawvere的Python项目详细描述
什么?
功能工具:(de)带类型检查的组合,多重分派。
为什么?
python中有很多函数工具:toolz、funcy、fn.py、pymonads…
它们很好,但是没有一个做类型检查,在我看来,从功能范式的观点来看,这是一个很大的损失。
如何?
使用复杂且不可维护的api:一个名为“arrow”的装饰器
对于箭头的technical解释,您可以查看:Understanding arrows
对于理论解释:“概念数学:范畴的第一次介绍”[f.william lawvere,stephen h.schanuel]是一个很好的开始。
先决条件
- 我强烈建议至少要有以下概念:
- lambda calculi(咖喱色)
- 代数符号中的元组(例如signatures)
- 图论基础(与范畴理论有关-态射、域、余域…)
目录
安装
从pypi安装:
pip install lawvere
或来源:
git clone git@github.com:apieum/lawvere.git cd lawvere python setup.py install
用法
快速入门:
for impatients
- arrow只接受两个可选参数:
- domain或source:它是类型的元组(如果是1元组,则仅是类型)
- 共域或target:(单一类型)
它返回一个函数装饰器
语法与Python2.7到3.x兼容。 如果只针对3.x版本,则可以使用注释而不是“arrow”参数。 “arrow”参数覆盖注释。
与2.x和3.x python版本兼容的代码。
fromlawvereimportarrow# obviously you don't need to use named parameters# it's just to illustrate their meaning.@arrow(domain=(int,int),codomain=int)defadd(x,y):returnx+y# currying:add2=add(2)assertadd2(3)==5assertadd(1)(2)==3# successive calls# composition (pipe):# pass the result of first function to secondadd4=add2>>add2assertadd4(1)==5# composition (circle):# pass result of add(1) into add4add5=add4<<add(1)assertadd5(5)==10# composed functions are tuples:assertisinstance(add4,tuple)assertadd5[1]==add4# equality is checked over signatures:assertadd(1)==add(1)assertadd5==add(1)>>add2>>add2# operator precedence:assertadd5==add(1)>>(add2<<add2)assertadd5==add2>>add2<<add(1)# Type Checking:type_checked=Falsetry:add('a','b')=='ab'exceptTypeError:type_checked=Trueasserttype_checked,'add should not exists for str types'# dispatch register# concat inherit arrow properties@add.register((str,str),str)defconcat(x,y):return"%s%s"%(x,y)# can still call/curry... concatassertconcat('a')('b')=='a b'# add with str call concatassertadd('a')==concat('a')# Concat is only defined for strtype_checked=Falsetry:assertconcat(1,2)==3exceptTypeError:type_checked=Trueasserttype_checked,'concat should not exists for int types'# Type Checking when composing:try:add>>concat(y='b')exceptTypeErrorasexc:message=str(exc)# hope message is clear :)assertmessage=="Cannot compose add -> int with concat(x:str=Undefined, y:str=b)"# if composition was circle message would be:# ... concat -> str with add(x:int=Undefined, y:int=Undefined)
代码仅与3.x版本兼容。
fromlawvereimportarrow@arrowdefadd(x:int,y:int)->int:returnx+y# identical use as Python 2 ## Type Checking:type_checked=Falsetry:add('a','b')=='ab'exceptTypeError:type_checked=Trueasserttype_checked,'add should not exists for str types'# dispatch@add.registerdefconcat(x:str,y:str)->str:return"%s%s"%(x,y)assertconcat('a','b')=='a b'# now add exists for str types:assertadd('a','b')=='a b'# type is also checked when composing... see python 2 ex.
开发
感谢您的反馈、代码评审、改进或错误,以及文档帮助。 你可以通过邮件联系我:apieum[在]gmail[点]com
测试建议要求:
pip install -r dev-requirements.txt
有时-规格颜色不起作用。卸载nosespec和nosecolor,然后按此顺序分别重新安装nosecolor和nosespec(先安装nosecolor)
启动测试:
git clone git@github.com:apieum/lawvere.git cd lawvere nosetests --with-spec --spec-color ./lawvere # or with watch # nosetests --with-spec --spec-color --with-watch ./lawvere