Package: pykell
PykellPython functional programming library inspired by Haskell.This is a personal project to deepen my understanding of functional programming by implementing this DSL in python.It is open-source, so feel free to open issues and pull requests!InstallingWe have a stable release under pypi:pipinstallpykellFeaturesThis DSL makes it easy to write functional programming patters with a clean syntax.FunctionsThis is an abstraction layer on top of Python regular functions and lambdas.frompykell.typingimportFunctionfrompykell.functionsimportF# Via a decorator pattern@Fdeff(x:int,y:float)->float:returnx+y# via a lambda (with type hints support)g=F[float,str](lambdax:f"This is a float:{x}")# automatic curying:f# Function[int, Function[float, float]]f2=f|2# application via | operatorf2_=f(2)# works just as fine!my_float=f2|1.5# compositionh=f2>>g# this will return ⃘⃘⃘⃘f ∘ gh|1.2# This is a float: 3.2# Chainingx=f|2|1.5ContainersThese are well known containers that can make your life easyer when programming.frompykell.typingimportMaybe,Just,Nothing,Error,Resultdeff(x:int)->Maybe[int]:returnJust(x+10)ifx<10elseNothing()deff(x:int)->Result[int,Exception]:returnJust(x+10)ifx<10elseError(Exception("This  is too big!!!"))FunctorsThis is some syntatic sugar to use functors in python.frompykell.typingimportFunctionfrompykell.functorsimportFunctor@Functordefint_to_str(f:Function[int,float])->Function[str,str]:returnlambdax:str(f(int(x)))# some functionsf=F[int,float](lambdax:x/7)g=F[int,float](lambdax:x*8)new_f:Function[str,str]=int_to_str(f)# this works# But this is cleaner!withint_to_str:# inside here all | calls go through the functorx=f|"1"# "0.14285714285714285"y=f|"3"# "24"z=f(7)# when calling with (), no functor is appliedContainersThese are well known containers that can make your life easyer when programming.frompykell.typingimportMaybe,Just,Nothing,Error,Resultdeff(x:int)->Maybe[int]:returnJust(x+10)ifx<10elseNothing()deff(x:int)->Result[int,Exception]:returnJust(x+10)ifx<10elseError(Exception("This  is too big!!!"))ArraysThis is inspired by other array language features but use haskells lazyness to do computations.frompykell.arraysimportarrresult=(arr([1,2,3]).map(lambdax:x+1).filter(lambdax:x%2!=0).fold(0,lambdaacc,cur:cur+acc))print(result._)# evaluates the expression:# you can do infinite calculations with it!defnaturals():i=0whileTrue:yield(i:=i+1)result=(arr(naturals()).map(lambdax:x+1).filter(lambdax:x%2!=0).take(10))print(result._)# 3, 5, 7, ...MonadsThis is a good one.frompykell.monadsimportMaybeMonadfrompykell.functionsimportFfrompykell.typingimportMaybe,Just,Nothing# define some functions we want to compose ...f=F[int,Maybe[int]](lambdax:Just(x+10)ifx<10elseNothing())g=F[int,Maybe[float]](lambdax:Just(x/7)ifx<10elseNothing())# Play inside the monadic environment!@MaybeMonad.dodefcalculate(x):y:int=yieldf(x)# yield calls with the bind.# Think of it like the let! in f# or x <- ... in Haskell.ify<5:# besides the yield everything works as normal!returny+5z:float=yieldg(z)returnz-1.5calculate(-10)# Just(5)calculate(4)# Just(2.0)calculate(11)# Nothing()ContributionsThis is just an experiment. If you have any ideas of features you want to see in here please reach out!