Just want to correct a typo, where I wrote: [(x, y), x <- xs, y <- ys, x > y"
I of course meant: [(x, y) | x <- xs, y <- ys, x > y] Keean. On 9 February 2015 at 14:16, Keean Schupke <[email protected]> wrote: > The RHS of the comprehension is the source and the notation of "x <- xs" > is equivalent to "for x in xs" where xs is any collection, and x is > assigned each value in the collection in turn, such that "x <- xs, y <- ys" > would iterate x and y though every combination of x and y from the source > containers. So really this is equivalent to: > > for y in ys do > for x in xs do > ... > > also on the RHS you can have filter terms like "x > y". So "x <- xs, y <- > ys, x > y" iterates through the cartesian product of "xs and ys" removing > terms where "x <= y". > > There is no reason for xs and ys to only be builtins, as long as the > generic interface the comprehension will use is defined. Consider how C++ > "for (x : xs) {...}" notation works where you would expand that into "for > (auto i = xs.begin(), auto& x = *i; i != xs.end(); ++i) {...}". The same > syntactic transformation can be applied so that f = [(x, y), x <- xs, y <- > ys, x > y" becomes: > > f.clear(); > for (auto j = ys.begin(), auto& y = *j; j != ys.end(); ++j ) { > for (auto i = xs.begin(), auto& x = *i; i != xs.end(); ++i) { > if (x > y) { > f.push_back(make_tuple(x, y)); > } > } > } > > Not only do we not care what they type of container "xs" and "ys" are > (they could be different), we don't care about the type of "f" either. All > we care is they implement the right interface. > > Keean. > > > > On 9 February 2015 at 12:48, Jonathan S. Shapiro <[email protected]> wrote: > >> On Sun, Feb 8, 2015 at 10:27 AM, Keean Schupke <[email protected]> wrote: >> >>> For me the most useful part of comprehension notation is the implicit >>> 'cartesian product', which other wise involves nested loops. It would be >>> best defined generically over containers using iterators. >>> >> >> That makes sense, but it isn't really addressing the question I was >> trying to ask. It's very possible that I don't have my terms right in this >> area. >> >> In my view - and please correct me if I have my terms wrong - a >> comprehension consists of a generator expression and a construction. The >> generator expression produces some form of collection. The construction >> takes this collection and turns it into some particular comprehended type >> (list, array, vector, possibly others). >> >> My question is: how do we get from the (arbitrary) collection to the >> (desired) final type? I'm especially mixed up about this when the desired >> final type is a sum type, because there is no obvious constructor to call. >> >> Is there some tricky thing going on here that allows us to infer the >> final desired type and build it directly as the generator executes? I >> confess I'm not seeing how that would work for array and vector >> comprehensions, where the size must be known in advance. >> >> Or should I stop trying to think of this as a construction problem, take >> the view that the generator produces a collection, and that the conversion >> to the final type is done by calling a function on that? in that view I can >> think about applying mixfix-like notions as a way to extend the >> comprehension constructs. So far as I know, all of the languages that do >> comprehensions only know how to do them over a "built in" set of types that >> are known to the parser. >> >> >> shap >> >> _______________________________________________ >> bitc-dev mailing list >> [email protected] >> http://www.coyotos.org/mailman/listinfo/bitc-dev >> >> >
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
