Skip to content

Instantly share code, notes, and snippets.

@qexat
Last active December 25, 2025 16:11
Show Gist options
  • Select an option

  • Save qexat/c7da40ed2f187751aec2e6346740529b to your computer and use it in GitHub Desktop.

Select an option

Save qexat/c7da40ed2f187751aec2e6346740529b to your computer and use it in GitHub Desktop.
functional programmers when they are forced to use python (they are crying and seething)
# ruff: noqa: D100, D103, A001, A002
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Callable
type List[T] = tuple[()] | tuple[T, List[T]]
def cons[T](first: T, rest: List[T]) -> List[T]:
return (first, rest)
def concat_in_reverse[T](
concatenatee: List[T],
concatenated: List[T],
) -> List[T]:
match concatenated:
case ():
return concatenatee
case (first, rest):
return concat_in_reverse((first, concatenatee), rest)
def reverse[T](list: List[T]) -> List[T]:
return concat_in_reverse((), list)
def concat[T](left: List[T], right: List[T]) -> List[T]:
return concat_in_reverse(left, reverse(right))
def map[T, U](func: Callable[[T], U], list: List[T]) -> List[U]:
match list:
case ():
return ()
case (first, rest):
return (func(first), map(func, rest))
def fold[T, Acc](
func: Callable[[Acc, T], Acc],
init: Acc,
list: List[T],
) -> Acc:
match list:
case ():
return init
case (first, rest):
return fold(func, func(init, first), rest)
def join[T](list: List[List[T]]) -> List[T]:
return fold(concat, (), list)
def bind[T, U](list: List[T], func: Callable[[T], List[U]]) -> List[U]:
return join(map(func, list))
# ruff: noqa: D100, D103, A001
from __future__ import annotations
from typing import TYPE_CHECKING
from typing import Final
if TYPE_CHECKING:
from collections.abc import Callable
from list import List
type Maybe[T] = tuple[()] | tuple[T]
nothing: Final = ()
def some[T](value: T) -> Maybe[T]:
return (value,)
def fold[T, U](nothing: U, some: Callable[[T], U], maybe: Maybe[T]) -> U:
match maybe:
case ():
return nothing
case (value,):
return some(value)
def bind[T, U](maybe: Maybe[T], func: Callable[[T], Maybe[U]]) -> Maybe[U]:
return fold((), func, maybe)
def map[T, U](func: Callable[[T], U], maybe: Maybe[T]) -> Maybe[U]:
return bind(maybe, lambda x: some(func(x)))
def join[T](maybe: Maybe[Maybe[T]]) -> Maybe[T]:
return bind(maybe, lambda x: x)
def get[T](maybe: Maybe[T], default: T) -> T:
return fold(default, lambda x: x, maybe)
def all_or_nothing[T](maybes: List[Maybe[T]]) -> Maybe[List[T]]:
match maybes:
case ():
return some(())
case ((), _):
return ()
case ((first,), rest):
return map(lambda rest: (first, rest), all_or_nothing(rest))

Comments are disabled for this gist.