sql - Implement DISTINCT in for comprehension -
in penultimate lecture of his coursera course, prof. odersky offered following for comprehension final step in lovely case study:
def solutions(target: int): stream[path] = { pathset <- pathsets path <- pathset if path.endstate contains target } yield path in earlier lecture drew analogies between for comprehensions , sql.
what i'm looking way yield paths have distinct endstate.
is there way refer within filter clause of same comprehension items have been yielded?
another approach might convert pathsets map endstate path before for statement, convert stream before returning it. however, seem lose lazy computation benefits of using stream.
an earlier method same case study accomplished similar goals, recursive function, while 1 doesn't (seem to) need recursive.
it looks use mutable set track endstates yielded, feels unsatisfying, since course has avoided using mutability far.
is there way refer within filter clause of same comprehension items have been yielded?
your comprehension desugars more or less like
pathsets flatmap { pathset => pathset filter { path => path.endstate contains target } } map {path => path} the last map identity function yield. can't remember if spec allows map elided when it's identity function.
anyway, hope shows more why there's no "reaching back" structure.
you can write lazy, recursive distinctby function
implicit class distinctstream[t](s: stream[t]) { def distinctby[v](f: t => v): stream[t] = { def distinctby(remainder: stream[t], seen:set[v]): stream[t] = remainder match { case head #:: tail => val value = f(head) if (seen contains value) distinctby(tail, seen) else stream.cons(head, distinctby(tail, seen + value)) case empty => empty } distinctby(s, set()) } } and use so
def solutions(target: int): stream[path] = (for { pathset <- pathsets path <- pathset if path.endstate contains target } yield path) distinctby (_.endstate) yeah, there's recursion. there because stream's map, flatmap, , filter functions lazy recursive functions already.
Comments
Post a Comment