views:

402

answers:

2
+5  Q: 

Haskell to Clojure

+2  A: 

This is closely following the Haskell implementation as far as my limited Haskell fu allows me to do....

(defn split
  [s]
  (map #(split-at % s) (range 1 (count s))))

(defn ne
  [s]
  (every? (complement empty?) s))

(defn nesplit
  [s]
  (filter ne (split s)))

(declare combine)

(defn exprs
  [s]
  (when-let [s (seq s)]
    (if (next s)
      (for [[ls rs] (nesplit s)
            l       (exprs ls)
            r       (exprs rs)
            e       (combine l r)]
        e)
      s)))

Haven't tested it though.

As for your error message: I think the problem is, that you don't call split recursively in exprs. Then you get 1 were a sequence is expected...

Random other note: count is linear in time for sequences. Since we just need to know, whether we have more than one element, we can check the value of (next s) against nil.

kotarak
Anyway: we call `count` in `split` anyway. So nevermind.
kotarak
+1  A: 

the exception results from exprs being called recursively and eventually being invoked with a list of integers. your code only handles a list of lists or a list of length one.

(exprs '(2 3 4))

leads to the else branch of the if statement which expands out to:

(map #(concat (exprs (first %)) (exprs (second %))) '(2 3 4))))

which comes out to:

(concat (exprs (first 2)) (exprs (second 2))) 
(concat (exprs (first 3)) (exprs (second 3))) 
(concat (exprs (first 4)) (exprs (second 4))) 

and (first 2) throws:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer 
miaubiz