@ -0,0 +1 @@ | |||||
test |
@ -0,0 +1,6 @@ | |||||
all: test | |||||
test: | |||||
g++ -Iinclude --std=c++17 -o test tests/*.cpp |
@ -0,0 +1,2 @@ | |||||
#pragma once | |||||
#include "combinations/all.hpp" |
@ -0,0 +1,5 @@ | |||||
#pragma once | |||||
#include "combinations/function.hpp" | |||||
#include "combinations/compose.hpp" | |||||
#include "combinations/tuple.hpp" | |||||
#include "combinations/curry.hpp" |
@ -0,0 +1,47 @@ | |||||
#pragma once | |||||
#include "combinations/tuple.hpp" | |||||
namespace cl{ | |||||
struct sigil_t{ | |||||
constexpr sigil_t(){} | |||||
}; | |||||
sigil_t sigil; | |||||
template<typename a, typename ...c> | |||||
class compose{ | |||||
// f . next | |||||
a f; | |||||
compose<c...> next; | |||||
public: | |||||
compose(a fn1, c ...oth) | |||||
: f{fn1} | |||||
, next{oth...} | |||||
{} | |||||
template<typename ...t> | |||||
auto operator()(t ...Args){ | |||||
return next(f(Args...)); | |||||
} | |||||
}; | |||||
template<typename a> | |||||
class compose<a>{ | |||||
// f . g | |||||
a f; | |||||
public: | |||||
compose(a fn1) | |||||
: f{fn1} | |||||
{} | |||||
template<typename ...t> | |||||
auto operator()(t ...Args){ | |||||
return f(Args...); | |||||
} | |||||
}; | |||||
template<typename a, typename b> | |||||
auto operator*(a fn1, b fn2) | |||||
{ | |||||
return compose(fn1, fn2); | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
#pragma once | |||||
namespace cl | |||||
{ | |||||
template<typename a, typename fn> | |||||
class curry | |||||
{ | |||||
a param; | |||||
fn call; | |||||
public: | |||||
curry(a p, fn func) | |||||
: param{p} | |||||
, call{func} | |||||
{} | |||||
template<typename ...b> | |||||
auto operator()(b ...Args){ | |||||
return call(param, Args...); | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,28 @@ | |||||
#pragma once | |||||
#include "combinations/curry.hpp" | |||||
namespace cl | |||||
{ | |||||
template <typename a> | |||||
class function{ | |||||
a me; | |||||
public: | |||||
function(a value) | |||||
: me(value) | |||||
{} | |||||
template<typename ...b> | |||||
auto operator()(b ...Args){ | |||||
return me(Args...); | |||||
} | |||||
template<typename cur, typename ...b> | |||||
auto operator()(cur arg){ | |||||
return curry(arg, me); | |||||
} | |||||
}; | |||||
template<typename invokable, typename ret, typename ...Args> | |||||
ret invoke(invokable fn, Args ...args) | |||||
{ | |||||
return fn(args...); | |||||
} | |||||
} |
@ -0,0 +1,28 @@ | |||||
#pragma once | |||||
#include <stddef.h> | |||||
namespace cl | |||||
{ | |||||
template<typename a, typename ...b> | |||||
class tuple{ | |||||
a _mine; | |||||
tuple<b...> _child; | |||||
template<size_t idx, a, b...> | |||||
friend a get(); | |||||
public: | |||||
tuple(a mine, b ...child) | |||||
: _mine(mine) | |||||
, _child(child...) | |||||
{} | |||||
}; | |||||
template<size_t idx, typename ...a> | |||||
constexpr auto get(tuple<a...> v) | |||||
{ | |||||
if constexpr (idx!=0) | |||||
return get<idx-1>(v._child); | |||||
else | |||||
return v._mine; | |||||
} | |||||
} |
@ -0,0 +1,15 @@ | |||||
#include "2CL.hpp" | |||||
#include <assert.h> | |||||
struct test_001{ | |||||
test_001() | |||||
{ | |||||
auto fn = cl::compose( | |||||
[](int a)->int{return a+2;}, | |||||
[](int a)->int{return a*2;} | |||||
); | |||||
assert(fn(1)==6); | |||||
} | |||||
}; | |||||
test_001 run_001; |
@ -0,0 +1,4 @@ | |||||
int main() | |||||
{ | |||||
return 0; | |||||
} |