简体   繁体   中英

concatenating sequences in 4clojure function

I just finished 4clojure Problem 60 , here's the code for my first program with the problem description:

;;Write a function which behaves like reduce, but returns each intermediate
;;value of the reduction. Your function must accept either two or three arguments,
;;and the return sequence must be lazy.
(fn red
  ([fun sq]
     (red fun (first sq) (rest sq)))
  ([fun acum sq]
   (if (empty? sq) acum
     (cons acum (lazy-seq (red fun (fun acum (first sq)) (rest sq)))))))

The core of the function occurs one line bellow the if, I just return the initial value followed by applying it to the next element in the sequence. But it fails for the second test case involving vectors:

user=> (red conj [1] [2 3 4])
([1] [1 2] [1 2 3] 1 2 3 4);; it should be ([1] [1 2] [1 2 3] [1 2 3 4])

It took me some time to realize that the problem was the cons which just adds the vector [1 2 3 4] as it were the rest of the list instead as a single element.

What I did is to convert cons to concat and acum to [acum] and it worked:

(fn red
  ([fun sq]
     (red fun (first sq) (rest sq)))
  ([fun acum sq]
   (if (empty? sq) [acum]
     (concat [acum] (lazy-seq
                     (red fun (fun acum (first sq)) (rest sq)))))))

Don't ask me why but it seems to me kind of inelegant, the other solutions didn't use concat neither.

The question is, considering the first function as it is, what function/macro does the work without modifying the code too much.

如果是, if返回[acum]而不是acum

You can avoid the use of concat if you take cons instead. Cons is lazy (see the discussion of cons vs. conj on Stack Overflow):

(defn my-reductions
  ([f sq] (my-reductions f (first sq) (rest sq)))
  ([f init sq]
    (if (empty? sq)
      (list init) 
      (cons init (lazy-seq (my-reductions f (f init (first sq)) (rest sq))))
    )
  )
)

Btw: This code passes the 4Clojure tests, but doesn't quite behave like reductions in all cases:

(my-reductions + [])  
(nil)  
(reductions + [])  
(0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM