Skip to content

Instantly share code, notes, and snippets.

@Sinha-Ujjawal
Last active October 23, 2022 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sinha-Ujjawal/36846458043706580cded46e41d7e70e to your computer and use it in GitHub Desktop.
Save Sinha-Ujjawal/36846458043706580cded46e41d7e70e to your computer and use it in GitHub Desktop.
Either type in Python
from typing import Generic, Tuple, TypeVar, Iterable, List, Optional, Any, Union
L = TypeVar("L")
R = TypeVar("R")
# SKI+ Combinators
S = lambda f: lambda g: lambda x: f(x)(g(x))
K = lambda x: lambda y: x
I = S(K)(K(K))
KI = K(I)
B = S(K(S))(K)
T = B(S(I))(K)
V = S(B(B)(B(S)(T)))(K(K))
# Definition of Pair
class Pair(Generic[L, R]):
def __init__(self) -> None:
raise NotImplementedError("Should not be used")
def __call__(self, func):
return self(func)
def mk_pair(left: L, right: R) -> Pair[L, R]:
return V(left)(right)
def fst(p: Pair[L, R]) -> L:
return p(K)
def snd(p: Pair[L, R]) -> R:
return p(KI)
def unpack(p: Pair[L, R]) -> Tuple[L, R]:
return fst(p), snd(p)
# Definition of Either type
class Either(Generic[L, R]):
def __init__(self) -> None:
raise NotImplementedError("Should not be used")
def __call__(self, func):
return self(func)
def either_left(value: L) -> Either[L, R]:
return mk_pair(K, value)
def either_right(value: R) -> Either[L, R]:
return mk_pair(KI, value)
def is_left(e: Either[L, R]) -> bool:
return fst(e)(True)(False)
def is_right(e: Either[L, R]) -> bool:
return fst(e)(False)(True)
def value_either(e: Either[L, R]) -> Union[L, R]:
return snd(e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment