For better computation composing in Python
- To bring the ability of composing computations in the functional way
- Make my life easier
- Exact clone of Haskell
- Blazing fast / super efficient
- Because I can
- Python may be amazing in some field, but sucks from the functional perspective
- Because I can
- Python is still used in my work place
With pip:
pip install fppy
Given Functors f, g:
__fmap__ :: f a -> (a -> b) -> f b__ntrans__ :: f a -> (f a ~> g b) -> g b
|=__fmap__&=__ntrans__
fmap=__fmap__
Given Functors f, g:
__trans__ :: f a ~> g b
No new trait comparing to functor, liftA2 is defined using fmap
Given Monad m:
__bind__ :: m a -> (a -> m b) -> m b
>>=__bind__
@do(Monad)enables do notation in the decorated function, where the explicitreturnstatement will be treated asretfrom the givenMonadtype, if noreturnstatement is given, the last element on the stack will be returned.name <- computationbinds the computation to the following block, calling the__bind__method of the monad object returned fromcomputationwith the namename.(name1, name2, ..., namen) <- computationworks in the similar way as the single name binding, this applys the binding function to the tuple contained within the monad object instead of calling the function directly.name1, name2, ..., namen <- computationsame as above
Maybe[T]Just[T] : Maybe[T]Nothing[T] : Maybe[T]
isJust :: Maybe[T] -> boolisNothing :: Maybe[T] -> boolfromJust :: Maybe[T] -> TfromMaybe :: T -> Maybe[T] -> Tmaybe :: S -> (T -> S) -> Maybe[T] -> SmapMaybe :: (T -> Maybe[S]) -> List[T] -> List[S]
Either[T]Left[T] : Either[T]Right[T] : Either[T]
Under[T]Undersimilar to Haskell'sIdentitymonad
Cont[T, R]
cont :: (A -> B) -> Cont[A, B]runCont :: Cout[B, C] -> C
Given functor f:
forget: NTrans[F, B, Under, T] :: f b ~> Under[T]
id_ :: T -> Tconst :: T -> A -> Tflip :: (B -> A -> T) -> A -> B -> Tfix :: (A -> A) -> Aon :: (B -> B -> T) -> (A -> B) -> A -> A -> T
-- not so well typed
NArg :: Nat -> Type
NArg (S Z) = A
NArg (S n) = A -> (NArg n)
NTpl :: (n:Nat) -> (NArg n) -> Type
NTpl (S Z) A =( A,)
NTpl (S n) (A -> NArg n) = cons A (NTpl n (NArg n))
constN :: (n:Nat) -> A -> (NArg n) -> AuncurryN :: (n:Nat) -> args:(NArg n) -> A -> ((NTpl n args) -> A)
__compose__
^=__compose__
__underlying__Delegate an attribute access to an underlying object
func : ComposableSignatureMismatchErrorNotEnoughArgsError
Seq : funcMap : func
transN(n, f, it) := it[n] = f(it[n])getN(n, it) := it[n]setN(n, v, it) := it[n] = veqN(n, it, x) := it[n] == xmapN(n, fn, lsts) := map(fn, zip(lst1, lst2 ... lstn))of_(v1 ... vn) := _ in (v1 ... vn)is_(t) := isinstance(_, t)and_(a, b) := a(_) and b(_)or_(a, b) := a(_) or b(_)to(dst, src) := dst(src)apply(fn) := fn(*a, **k)fwd_ = Under.ret
trans0trans1get0get1set0set1eq0eq1mp1mp2
parser[S, T] :: [S] -> Either [S] ([T] * [S])
*=parser.timeN+=parser.concat|=parser.choice>>=parser.parseR<<=parser.parseL
one :: (S -> bool) -> parser[S, S]neg :: (S -> bool) -> parser[S, S]just_nothing :: parser[S, T]pmaybe :: parser[S, T] -> parser[S, T]many :: parser[S, T] -> parser[S, T]many1 :: parser[S, T] -> parser[S, T]ptrans :: parser[S, T] -> (T -> Y) -> parser[S, Y]peek :: parser[S, T] -> parser[S, T]skip :: parser[S, T] -> parser[S, T]pseq :: [S] -> parser[S, T]inv :: parser[S, T] -> parser[S, T]
GPL3+
