Le 16/12/14 22:53, paul Fultz a écrit :
Ok, I think I understand what you are aksing for. This how I would approach the problem using Tick. It does require defining different traits to get there(I am not sure how it could be done all in one take). First, I would define `is_callable` that checks if a function is called with `T` and returns `U`:
TICK_TRAIT(is_callable) { template
auto requires_(F&& f, T&& t, U&&) -> tick::valid< decltype(returns<U>(f(std::forward<T>(t)))) >; }; Next I would write a trait that checks if the two types, `Wt` and `Wu`, are mapped like `W<T> -> W<U>` and that the function takes `T` and returns `U`:
template
struct is_mapped : std::false_type {}; template class W, class T, class U, class F> struct is_mapped
: is_callable {}; And then I would write the `is_functor` to call the `map` function and check that it returns a mapped type:
TICK_TRAIT(is_functor) { template
auto requires_(F&& f, Wt&& wt) -> tick::valid< decltype(returns ( map(f, std::forward<Wt>(wt)) )) >; }; Does that make sense? Is this what you are asking for?
No, this trait has two parameters F and Wt. I'm looking for a trait with a single parameter W, the type constructor. Maybe I'm looking for a thing that should not exists ;-)
But this is not exactly what I want to conceptualize. The wrapped type T and the function F should be universally quantified, that is, the concept concerns only the type constructor W: Functor<W>.
I have a problem introducing the universal quantification of T and F. I don't know how to do it without using again a template.
concept Functor<typename W> = template
// universal quantification on T and F requires { using WT = ApplyType ; using U = ResultType ; using WU = ApplyType ; Function && requires (F f, WT wt) { WU { map(f, wt) }; } } }; But this is not valid code, isn't it.
Is there something wrong with this kind of concepts? What would be the best way to conceptualize this kind of concepts with the Tick library ?
Vicente