https://github.com/JoelLefkowitz/funky
Functional type classes and instances.
https://github.com/JoelLefkowitz/funky
applicative functional functor instance monad
Last synced: 8 months ago
JSON representation
Functional type classes and instances.
- Host: GitHub
- URL: https://github.com/JoelLefkowitz/funky
- Owner: JoelLefkowitz
- License: mit
- Created: 2024-05-01T16:59:09.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-12-29T15:41:12.000Z (9 months ago)
- Last Synced: 2024-12-29T16:29:40.159Z (9 months ago)
- Topics: applicative, functional, functor, instance, monad
- Language: C++
- Size: 111 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Funky
Expressible and immutable methods for generics.

## Installing
```bash
conan install funky
```You can also download the [sources](https://download-directory.github.io?url=https://github.com/JoelLefkowitz/funky/tree/master/src).
## Motivation
Rather than this:
```cpp
#include
#include
#includestd::vector numbers({1, 2, 3});
std::vector output;std::transform(
numbers.begin(),
numbers.end(),
std::back_inserter(output),
[](auto x) { return x + 1; }
);
```Let's write this:
```cpp
#include
#includestd::vector numbers({1, 2, 3});
auto output = map>(
[](auto x) { return x + 1; },
numbers
);
```Now `output` will still be:
```cpp
std::vector({2, 3, 4});
```And this function doesn't mutate the input and is much easier to read.
> Most structures are small enough that immutability makes transformations easier to read and thread safe without loss of performance.
The C++ templating system is smart enough to evaluate the types involved in these kinds of transformations for us. This means we can avoid using std::function or interfaces to declare the types involved. This also means we don't need to define concepts for `Functor` or `Foldable` to use `map` and `fold`.
Our `map` function makes an empty container and still uses `.begin()` and `.end()` internally to map the results. This makes it just as generic as `std::transform` and suitable for transforming any iterable structure. This is reflected in its type signature:
```cpp
// map ≔ (A → B) → [ A ] → [ B ]
```## Documentation
Documentation and more detailed examples are hosted on [Github Pages](https://joellefkowitz.github.io/funky).
## Usage
This package makes use of templates. The definitions and implementations are split between `.hpp` and `.tpp` files. If you are calling the functions implemented in them then include the `.tpp` file instead.
## Overview
### Ranges
Available in: `funky/vectors/ranges.hpp`
#### range
`size_t → std::vector`
```cpp
std::vector range(size_t limit);
````T → T → T → std::vector`
```cpp
std::vector range(T start, T stop, T step = 1);
```#### linspace
`T → T → size_t → std::vector`
```cpp
std::vector linspace(T start, T stop, size_t count);
```#### enumerate
`std::vector → std::vector>`
```cpp
std::vector> enumerate(const std::vector &vec);
```### Mutable
Available in: `funky/vectors/mutable.hpp`
#### insert
`std::vector → std::vector → void`
```cpp
void insert(const std::vector &source, std::vector &target);
```#### erase
`std::vector → T → void`
```cpp
void erase(std::vector &vec, T x);
```#### move_to_back
`(T → bool) → std::vector → void`
```cpp
void move_to_back(const std::function &filter,std::vector &vec);
```### Immutable
Available in: `funky/vectors/immutable.hpp`
#### unique
`std::vector → std::vector`
```cpp
std::vector unique(const std::vector &vec);
```#### reverse
`std::vector → std::vector`
```cpp
std::vector reverse(const std::vector &vec);
```#### difference
`std::vector → std::vector → std::vector`
```cpp
std::vector difference(const std::vector &source,const std::vector &target);
```#### intersection
`std::vector → std::vector → std::vector`
```cpp
std::vector intersection(const std::vector &source,const std::vector &target);
```#### slice
`std::vector → size_t → size_t → std::vector`
```cpp
std::vector slice(const std::vector &vec,const size_t start,const size_t end);
```#### slice_first
`std::vector → size_t → std::vector`
```cpp
std::vector slice_first(const std::vector &vec, size_t width);
```#### slice_last
`std::vector → size_t → std::vector`
```cpp
std::vector slice_last(const std::vector &vec, size_t width);
```#### drop_first
`std::vector → size_t → std::vector`
```cpp
std::vector drop_first(const std::vector &vec, size_t width);
```#### drop_last
`std::vector → size_t → std::vector`
```cpp
std::vector drop_last(const std::vector &vec, size_t width);
```#### aperture
`std::vector → size_t → std::vector>`
```cpp
std::vector> aperture(const std::vector &vec,size_t width);
```#### concat
`std::vector → T → std::vector`
```cpp
std::vector concat(const std::vector &vec, const T &x);
````std::vector → std::vector → std::vector`
```cpp
std::vector concat(const std::vector &vec, const std::vector &x);
```#### flatten
`std::vector> → std::vector`
```cpp
std::vector flatten(const std::vector> &vec);
```#### from_deque
`std::deque → std::vector`
```cpp
std::vector from_deque(const std::deque &deque);
```### Elements
Available in: `funky/vectors/elements.hpp`
#### min
`std::vector → T`
```cpp
T min(const std::vector &vec);
```#### max
`std::vector → T`
```cpp
T max(const std::vector &vec);
```#### index
`std::vector → T → size_t`
```cpp
size_t index(const std::vector &vec, const T &x);
````(const T & → bool) → std::vector → size_t`
```cpp
size_t index(std::function condition,const std::vector &vec);
```#### contains
`std::vector → T → bool`
```cpp
bool contains(const std::vector &vec, const T &x);
```#### repeats
`std::vector → bool`
```cpp
bool repeats(const std::vector &vec);
```#### overlaps
`std::vector → std::vector → bool`
```cpp
bool overlaps(const std::vector &source, const std::vector &target);
```### Accumulators
Available in: `funky/vectors/accumulators.hpp`
#### average
`std::vector → T`
```cpp
T average(const std::vector &vec);
```### Strings
Available in: `funky/strings/strings.hpp`
#### reverse_copy
`std::string → std::string`
```cpp
std::string reverse_copy(const std::string &str);
```#### pad
`std::string → size_t → std::string`
```cpp
std::string pad(const std::string &str, size_t size);
```#### chunk
`std::string → size_t → std::vector`
```cpp
std::vector chunk(const std::string &str, size_t size);
```#### split
`std::string → std::string → std::vector`
```cpp
std::vector split(const std::string &str,const std::string &delimiter);
```#### starts_with
`std::string → std::string → bool`
```cpp
bool starts_with(const std::string &str, const std::string &prefix);
```#### ends_with
`std::string → std::string → bool`
```cpp
bool ends_with(const std::string &str, const std::string &suffix);
```#### uppercase
`std::string → std::string`
```cpp
std::string uppercase(const std::string &str);
```#### lowercase
`std::string → std::string`
```cpp
std::string lowercase(const std::string &str);
```#### truncate
`std::string → size_t → std::string → std::string`
```cpp
std::string truncate(const std::string &str,size_t limit,const std::string &ellipsis = "...");
```#### join
`std::vector → std::string → std::string`
```cpp
std::string join(const std::vector &strings,const std::string &delimiter = "");
```#### remove_substrings
`std::string → std::vector → std::string`
```cpp
std::string remove_substrings(const std::string &str,const std::vector &substr);
```### Hex
Available in: `funky/strings/hex.hpp`
#### hex
`int → size_t → std::string`
```cpp
std::string hex(int n, size_t length);
```#### parse_hex
`std::string → int`
```cpp
int parse_hex(const std::string &str);
```### Numbers
Available in: `funky/numbers/numbers.hpp`
#### frac
`double → double`
```cpp
double frac(double x);
```#### round
`double → size_t → double`
```cpp
double round(double x, size_t dps);
```#### sign
`int → int`
```cpp
int sign(int n);
```#### order
`double → int`
```cpp
int order(double n);
```#### units_prefix
`double → std::string`
```cpp
std::string units_prefix(double n);
```### Limits
Available in: `funky/numbers/limits.hpp`
#### between
`T → T → T → bool`
```cpp
bool between(T lower, T x, T higher);
```#### contains
`T → T → T → bool`
```cpp
bool contains(T lower, T x, T higher);
```#### clamp
`T → T → T → T`
```cpp
T clamp(T lower, T x, T higher);
```#### clamp_proportion
`double → double`
```cpp
double clamp_proportion(double x);
```#### normalise
`double → double → double → double → double`
```cpp
double normalise(double x, double min, double max, double scale);
```### Division
Available in: `funky/numbers/division.hpp`
#### factor
`int → int → bool`
```cpp
bool factor(int dividend, int divisor);
```#### ratio
`size_t → double → double`
```cpp
double ratio(size_t dividend, double divisor);
````double → size_t → double`
```cpp
double ratio(double dividend, size_t divisor);
````size_t → size_t → double`
```cpp
double ratio(size_t dividend, size_t divisor);
```### Zip
Available in: `funky/iterables/zip.hpp`
#### zip
`[ A ] → [ B ] → std::vector>`
```cpp
std::vector> zip(const FA &a, const FB &b);
```### Product
Available in: `funky/iterables/product.hpp`
#### product
`[ A ] → [ B ] → std::vector>`
```cpp
std::vector> product(const FA &a, const FB &b);
```### Pair
Available in: `funky/iterables/pair.hpp`
#### pair
`[ A ] → std::vector>`
```cpp
std::vector> pair(const FA &source);
```### Map
Available in: `funky/iterables/map.hpp`
#### map
`(char → char) → std::string → std::string`
```cpp
std::string map(const T &mapper, const std::string &source);
````(A → B → C) → std::map → std::vector`
```cpp
std::vector map(const T &mapper, const std::map &source);
````(A → B) → [ A ] → [ B ]`
```cpp
FB map(const T &mapper, const FA &source);
```### Foreach
Available in: `funky/iterables/foreach.hpp`
#### foreach
`(A → void) → [ A ] → void`
```cpp
void foreach (const T &effect, const FA &source);
````(A → size_t → void) → [ A ] → void`
```cpp
void foreach (const T &effect, const FA &source);
````(A → B → void) → [ A ] → [ B ] → void`
```cpp
void foreach (const T &effect, const FA &a, const FB &b);
````(A → B → size_t → void) → [ A ] → [ B ] → void`
```cpp
void foreach (const T &effect, const FA &a, const FB &b);
```### Fold
Available in: `funky/iterables/fold.hpp`
#### fold
`(B → A → B) → B → [ A ] → B`
```cpp
B fold(const T &folder, const B &initial, const FA &source);
```### Filter
Available in: `funky/iterables/filter.hpp`
#### filter
`(A → bool) → [ A ] → [ A ]`
```cpp
FA filter(const T &condition, const FA &source);
```### Pipe
Available in: `funky/callables/pipe.hpp`
#### pipe
`T → U → auto`
```cpp
auto pipe(const T &f, const U &...gs);
```### Compose
Available in: `funky/callables/compose.hpp`
#### compose
`T → U → auto`
```cpp
auto compose(const T &f, const U &g);
````T → U → auto`
```cpp
auto compose(const T &f, const U &...gs);
```### Booleans
Available in: `funky/booleans/booleans.hpp`
#### all
`[ A ] → bool`
```cpp
bool all(const FA &source);
````(A → bool) → [ A ] → bool`
```cpp
bool all(const T &mapper, const FA &source);
```#### any
`[ A ] → bool`
```cpp
bool any(const FA &source);
````(A → bool) → [ A ] → bool`
```cpp
bool any(const T &mapper, const FA &source);
```#### at_least
`size_t → [ A ] → bool`
```cpp
bool at_least(size_t min, const FA &source);
````(A → bool) → size_t → [ A ] → bool`
```cpp
bool at_least(const T &mapper, size_t min, const FA &source);
```## Tooling
### Dependencies
To install dependencies:
```bash
yarn install
pip install .[all]
conan install .
```### Tests
To run tests:
```bash
scons test
```### Documentation
To generate the documentation locally:
```bash
scons docs
```### Linters
To run linters:
```bash
scons lint
```### Formatters
To run formatters:
```bash
scons format
```## Contributing
Please read this repository's [Code of Conduct](CODE_OF_CONDUCT.md) which outlines our collaboration standards and the [Changelog](CHANGELOG.md) for details on breaking changes that have been made.
This repository adheres to semantic versioning standards. For more information on semantic versioning visit [SemVer](https://semver.org).
Bump2version is used to version and tag changes. For example:
```bash
bump2version patch
```### Contributors
- [Joel Lefkowitz](https://github.com/joellefkowitz) - Initial work
## Remarks
Lots of love to the open source community!
![]()
![]()
![]()