Skip to content

Instantly share code, notes, and snippets.

@minoki
Created September 14, 2011 22:26
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 minoki/1217991 to your computer and use it in GitHub Desktop.
Save minoki/1217991 to your computer and use it in GitHub Desktop.
/*
bind1 :: (a -> b) -> a -> b
bind1 f t0 = f t0
*/
template<typename R, typename F, typename T0>
struct bind1_impl {
bind1_impl(F f,T0 t0):f(f),t0(t0){}
template<typename... T>
R operator()(T... t) {
return static_cast<R>(f(t0, t...));
}
F f;
T0 t0;
};
template<typename R, typename F, typename T0>
inline bind1_impl<R, F, T0> bind1(F f, T0 t0) {
return bind1_impl<R, F, T0>(f, t0);
}
/*
apply_tuple f t = apply_impl f t 0 where
apply_impl f t n | n == length t = f
apply_impl f t n = apply_impl (f (t !! n)) t (n+1)
*/
template<typename R, typename Tuple, int N = 0,
bool = (std::tuple_size<Tuple>::value==N)>
struct apply_impl;
template<typename R, typename Tuple, int N>
struct apply_impl<R, Tuple, N, true> {
template<typename F>
static R apply(F f, Tuple const&) {
return static_cast<R>(f());
}
};
template<typename R, typename Tuple, int N, bool>
struct apply_impl {
template<typename F>
static R apply(F f, Tuple tuple) {
return apply_impl<R, Tuple, N+1>
::template apply(bind1<R>(f, std::get<N>(tuple)), tuple);
}
};
template<typename R, typename F, typename Tuple>
inline R apply_tuple(F f, Tuple tuple) {
return apply_impl<R, Tuple>
::template apply(f, tuple);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment