Skip to content

Instantly share code, notes, and snippets.

@niha
Created June 4, 2010 05:10
Show Gist options
  • Save niha/424985 to your computer and use it in GitHub Desktop.
Save niha/424985 to your computer and use it in GitHub Desktop.
// apply を利用した実装メモ
// primary
template <typename Ret, typename Args>
struct RetType;
template <typename Ret>
struct RetType<Ret, tuple<>> {
typedef Ret type;
};
template <typenamea Ret, typename Arg, typename ...Args>
struct RetType<Ret, tuple<Arg, Args...>> {
typedef typename RetType<Ret, tuple<Args...>>::type Partial;
typedef function<Partial (Arg)> type;
};
template <typename T>
struct curry_impl;
template <>
struct curry_impl<tuple<>> {
template <typename Ret, typename ...Args>
static auto impl(Ret (*fun)(Args...), tuple<Args...> t) -> Ret {
return apply(fun, t);
}
};
template <typename UnBoundArgsHead, typename ...UnBoundArgsTail>
struct curry_impl<tuple<UnBoundArgsHead, UnBoundArgsTail...>> {
template <typename Ret, typename ...Args, typename ...BoundArgs>
static auto impl(Ret (*fun)(Args...), tuple<BoundArgs...> t) -> typename RetType<Ret, tuple<UnBoundArgsHead, UnBoundArgsTail...>>::type {
return [](UnBoundArgsHead arg){ return curry_impl<tuple<UnBoundArgsTail...>>::impl(fun, tuple_cat(t, make_tuple(arg));
}
};
template <typename Ret, typename ...Args>
auto curry(Ret (*fun)(Args...)) -> typename RetType<Ret, tuple<Args...>>::type {
return curry_impl<tuple<Args...>>::impl(fun, make_tuple());
}
// 職場からなのでコンパイル試せてないけれど、こんな感じで…
// RetType は (Arg1 -> Arg2 ... -> ArgN) -> Ret な型を Arg1 -> (Arg2 -> ... (ArgN -> Ret) ... ) に変換する type function
// decltype(self) が無理なら返値型を計算してやろうの発想。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment