Hi all,

I am trying to implement a function that splits any given sequence on a
subsequence. I would like it to behave like this:

    user> (split-at-subsequence [5 6] (range 10))
    ((0 1 2 3 4) (7 8 9))
    user> (split-at-subsequence [5 7] (range 10))
    ((0 1 2 3 4 5 6 7 8 9))
    user> (first (second (split-at-subsequence [1 2] (range))))
    3

The code I have so far inserts sentinels for the given subsequence and then
returns chunks until a sentinel is found.

    (defn starts-with-subseq?
      "Returns true if the first sequence starts with the second one"
      [sub-seq coll]
      (let [pairs (map vector coll sub-seq)
            matching-pairs (take-while #(= (first %) (second %)) pairs)]
        (= (count matching-pairs) (count sub-seq))))

    (defn- replace-subseq-with-sentinel
      [sub-seq sentinel coll]
      (lazy-seq
       (when-let [s (seq coll)]
         (if (starts-with-subseq? sub-seq s)
           (cons sentinel
                 (replace-subseq-with-sentinel sub-seq sentinel (drop (count 
sub-seq) s)))
           (cons (first s)
                 (replace-subseq-with-sentinel sub-seq sentinel (rest s)))))))

    (defn- split-at-sentinel
      [sentinel coll]
      (take-nth 2 (partition-by #(= sentinel %) coll)))

    (defn split-at-subsequence
      [sub-seq coll]
      (let [sentinel (Object.)]
        (->> (replace-subseq-with-sentinel sub-seq sentinel coll)
             (split-at-sentinel sentinel)))

This does exactly what it should do, except for the fact that

    user> (first (second (split-at-subsequence [1 2] (range))))

never returns as it does not seem to be "lazy enough". What surprises me is
that

    user> (def sentinel (Object.))
    #'user/sentinel
    user> (take 5 (replace-subseq-with-sentinel [1 2] sentinel (range)))
    (0 #<Object java.lang.Object@272a335c> 3 4 5)

works just fine, so the problem must be in my implementation of
split-at-sentinel. I would be grateful for any pointers that might shed light
on this behaviour. I am using clojure 1.3 if that is of any importance.

Thanks for your time and may you have a nice day!
-- 
Wolodja <babi...@gmail.com>

4096R/CAF14EFC
081C B7CD FF04 2BA9 94EA  36B2 8B7F 7D30 CAF1 4EFC

Attachment: signature.asc
Description: Digital signature

Reply via email to