| >It takes an input range Which should have a type. >and returns a type that iterates through that range Which should have a type. The entire point is that this is a solved problem, there is no excuse to simply throw up our hands and say "screw documentation we'll just say this function is a mystery". Functor f => (a -> b) -> f a -> f b And please don't miss the point and tell me D doesn't have Functor. The entire point is that D has something, and it doesn't tell us what that something is. It should. Documentation is good. |
Or rather, D doesn't have concepts (of which 'Functor' is a special case); that is, the notion of a type that is characterized by having the ability to execute operations is not expressible in its typesystem.
Or rather, it is, but only with classes. You want something like "a return type; fulfilling the condition of being able to be used in this way." This is not something you can specify as a function attribute in D. Instead, ranges use a form of duck typing. The next step in the call chain can tell whether the previous step gave it something it can use using template inconditions, ie. `isInputRange!T`. But the previous step can't assert that it is returning a type that fulfills a constraint. In other words, there's type inconditions but not type outconditions.