All Projects → tek → Amino

tek / Amino

Licence: mit
functional data structures and utilities for python

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Amino

Result
The modelling for success/failure of operations in Kotlin
Stars: ✭ 705 (+2174.19%)
Mutual labels:  functional
Awaity.js
A functional, lightweight alternative to bluebird.js, built with async / await in mind.
Stars: ✭ 818 (+2538.71%)
Mutual labels:  functional
Erlach
☣⚫⚫ SPA Imageboad on WebSockets written on Erlang
Stars: ✭ 23 (-25.81%)
Mutual labels:  functional
Flix
The Flix Programming Language
Stars: ✭ 719 (+2219.35%)
Mutual labels:  functional
Remeda
A utility library for JavaScript and TypeScript.
Stars: ✭ 774 (+2396.77%)
Mutual labels:  functional
Kaur
A bunch of helper functions to ease the development of your applications.
Stars: ✭ 17 (-45.16%)
Mutual labels:  functional
Cljfx
Declarative, functional and extensible wrapper of JavaFX inspired by better parts of react and re-frame
Stars: ✭ 624 (+1912.9%)
Mutual labels:  functional
Immutable Tuple
Immutable finite list objects with constant-time equality testing (===) and no memory leaks.
Stars: ✭ 29 (-6.45%)
Mutual labels:  functional
Cowboy
Small, fast, modern HTTP server for Erlang/OTP.
Stars: ✭ 6,533 (+20974.19%)
Mutual labels:  functional
Composable Fetch
A library that brings composition to http requests & solves most common tasks
Stars: ✭ 23 (-25.81%)
Mutual labels:  functional
Syntax sugar python
A library adding some anti-Pythonic syntatic sugar to Python
Stars: ✭ 721 (+2225.81%)
Mutual labels:  functional
Sinuous
🧬 Light, fast, reactive UI library
Stars: ✭ 740 (+2287.1%)
Mutual labels:  functional
Farwest
Framework for building RESTful HATEOAS-driven applications.
Stars: ✭ 18 (-41.94%)
Mutual labels:  functional
Gun
HTTP/1.1, HTTP/2 and Websocket client for Erlang/OTP.
Stars: ✭ 710 (+2190.32%)
Mutual labels:  functional
Kotlin Options
Kotlin Options with functional operators
Stars: ✭ 25 (-19.35%)
Mutual labels:  functional
Meta Typing
📚 Functions and algorithms implemented purely with TypeScript's type system
Stars: ✭ 628 (+1925.81%)
Mutual labels:  functional
Vue Grid Styled
Lightweight set of functional grid components
Stars: ✭ 16 (-48.39%)
Mutual labels:  functional
Swiftlyext
SwiftlyExt is a collection of useful extensions for Swift 3 standard classes and types 🚀
Stars: ✭ 31 (+0%)
Mutual labels:  functional
Partial.lenses
Partial lenses is a comprehensive, high-performance optics library for JavaScript
Stars: ✭ 846 (+2629.03%)
Mutual labels:  functional
Phpfn
Functional PHP Toolstet: Centralized monorepository for all libraries
Stars: ✭ 19 (-38.71%)
Mutual labels:  functional

About

This library provides some functional data structures, utilities and a typeclass system that resemble those concepts in scala. Some of the implementations have considerable overhead and aren't suitable for performance critical applications; their purpose is nicer and familiar syntax and composability.

Anonymous functions

These are an alternative to lambdas with parameter placeholder wildcards. If the env var AMINO_ANON_DEBUG is set, a different implementation with severe performance penalties but literal string representation is used.

from amino import L, _, __

f = L(isinstance)(_, str)
f('amino')
# True

# for methods
f = __.index('n')
f('amino')
# 3

# for attributes
f = _.parent
f(Path('/home/user'))
# Path('/home')

Data

List

A wrapper for stdlib list with extended interface.

from amino import List, _

l = List(1, 2, 3, 4)
l.map(_ + 5)
# List(6, 7, 8, 9)

l = List(List(1, 2), List(3, 4))
l.flat_map(__.map(_ - 1))
# List(0, 1, 2, 3)

Maybe

An optional ADT with subtypes Just and Empty.

j = Just(1)
e = Empty()

j.map(List)
# Just(List(1))

e.map(_ + 2)
# Empty()

j.flat_map(lambda a: Just(a - 2))
# Just(-1)

Either

A simple coproduct type that can be inhabited by two types.

r = Right(5)
l = Left('error')

r.map(_ + 1)
# Right(6)

l.map(_ + 1)
# Left('error')

l.lmap(_ + ' in test')
# Left('error in test')

r.flat_map(lambda a: Left(a + 3))
# Left(8)

do notation

The function decorator do allows to use generators as do-blocks with any class that responds to flat_map. It is implemented by looping until the generator is exhausted, calling flat_map on each yielded effect and sending its value into the generator.

from amino import do

@do(Either[int, int])
def compute() -> Do:
  user = yield Right('root')
  content = yield IO.delay(Path('/etc/passwd').read_text).attempt
  yield Lists.lines(content).index_where(lambda l: user in l).to_either('not found')

All yielded values produce an Either, the return value is the found index or the error message from the last statement or the IO call.

return a behaves similar to Haskell, being equivalent to yield Monad[F].pure(a).

Typeclasses

Although these make a lot more sense with a real type system, they provide a nice abstraction for functionality. The map and flat_map operations, for instance, are implemented in the typeclasses Functor and FlatMap, for which instances are provided for arbitrary types, among them List and Maybe. The typeclasses define methods that are looked up in the data class' __getattr__, which is provided by the Implicits base class inherited by List and Maybe. The typeclass instances are stored in a global registry, which can be used separately from the Implicits concept:

from amino.tc.monad import Monad

Monad.lookup(List).flat_map(List(1, 2), lambda a: List(a + 5))
# List(6, 7)

Instances can be registered in several ways, the easiest of which is by passing the target type to the metaclass:

from typing import TypeVar, Callable
from amino.tc.functor import Functor

A = TypeVar('A')
B = TypeVar('B')

class ListFunctor(Functor, tpe=List):

  def map(l: List[A], f: Callable[[A], B]) -> List[B]:
    return List.wrap(map(f, l))

After importing the instance's module, the map method can be used as shown above.

IO

IO is a trampolined algebra for computation abstraction that catches errors:

t = IO.pure(Path('/var/log/dmesg')).flat_map(L(IO.delay)(__.read_text()))
# IO(Pure(/var/log/dmesg).flat_map(L(delay)(__.read_text())))

t.attempt
# Right('...'): Either[IOException, str]
# or
# Left(IOException('Pure(/var/log/dmesg).flat_map(L(delay)(__.read_text()))', [], PermissionError(13, 'Permission denied')))

StateT

StateT abstracts F[S => F[S, A]], implemented for several effects as EitherState etc. It offers the usual monadic constructors:

from amino.state import StateT, EitherState

@do
def state(x: int) -> typing.Generator[StateT[Either, str, int], Any, None]:
  i = yield EitherState.inspect_f(lambda s: Try(int, s))
  yield EitherState.modify(lambda a: len(a) * x + i)
  yield EitherState.pure(x)

s = state(5)
s.run('15') # -> Right((25, 5))

Data

The base class Dat makes working with pure data types simpler by analyzing a class' __init__ and creating class attributes containing info about its fields. This allows for simple copying (optionally with type check) without intrusive descriptor magic – a Dat instance is still a plain old python object.

class Data(Dat['Data'])

    def __init__(a: int, b: List[str]) -> None:
        self.a = a
        self.b = b

Data(7, List('one', 'two')).copy(a=3)

Json

amino provides a framework for Json de/encoding based on typeclasses. The functions encode_json, dump_json and decode_json look for instances of the typeclasses Encoder and Decoder to process data. Codecs for some builtins like Path and UUID as well as *amino's standard types like Either and Maybe are provided.

The most convenient aspect of this is that Dat will automatically call the corresponding De/Encoder for all its fields, making serialization of nested data structures trivial.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].