Skip to content

Instantly share code, notes, and snippets.

@cheroliv
Last active January 5, 2024 22:00
Show Gist options
  • Save cheroliv/a645871da540268cce8fc3d3531ffea7 to your computer and use it in GitHub Desktop.
Save cheroliv/a645871da540268cce8fc3d3531ffea7 to your computer and use it in GitHub Desktop.
python functional factorial
from functools import lru_cache
from pydantic import BaseModel
from pymonad.either import Left, Right
class Error(BaseModel):
message: str
def curry(func):
def curried(*args, **kwargs):
if len(args) + len(kwargs) >= func.__code__.co_argcount:
return func(*args, **kwargs)
return lambda *args2, **kwargs2: curried(*(args + args2), **(kwargs | kwargs2))
return curried
def sealed_class(name, *args, **kwargs):
return type(name,
(BaseModel,),
{'__annotations__': kwargs})
EitherResult = sealed_class('EitherResult',
right=Right,
left=Left)
@lru_cache
def memoize(func):
memo = {}
def helper(n):
if n not in memo:
memo[n] = func(n)
return memo[n]
return helper
@curry
def fact(n):
return (
Right(n) if n >= 0 else
Left(Error(message='Invalid input'))
).bind(lambda x:
Right(1)
if x == 0
else fact(x - 1).bind(lambda y: Right(x * y)))
def run_computation(n):
result = fact(n)
return result.value \
if result.is_right() \
else Error(message=result.value.message)
def main():
try:
computation_result = run_computation(int(input(
"Entrez un nombre entier pour calculer sa factorielle : "
)))
if isinstance(computation_result, int):
print(f"Le résultat de la factorielle est : {computation_result}")
elif isinstance(computation_result, Error):
print(f"Erreur : {computation_result.message}")
else:
print("Une erreur inattendue s'est produite.")
except ValueError:
print("Erreur : Veuillez entrer un nombre entier valide.")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment