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
path
s 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 endstate
s 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