I am going over this haskell lecture on count down game, i don't know any haskell but i am intrested in the problem, i am trying to port his code to clojure.
this is the part i got stuck must be something i don't get in haskell,
split :: [a] -> [([a],[a])]
split [] = [([],[])]
split (x:xs) = ([],x:xs) : [(x:ls,rs) | (ls,rs) [([a],[a])]
nesplit = filter ne . split
ne :: ([a],[b]) -> Bool
ne (xs,ys) = not (null xs || null ys)
exprs :: [Int] -> [Expr]
exprs [] = []
exprs [n] = [Val n]
exprs ns = [e | (ls,rs)
I have my own split given 1 2 3 4 it spits out,
(((1) (2 3 4)) ((1 2) (3 4)) ((1 2 3) (4)))
(defn split [v]
(if (= (count v) 1)
(list (first v))
(map #(list (take % v) (drop % v)) (range 1 (count v)))))
(defn exprs [v]
(if (= (count v) 1)
v
(map #(concat (exprs (first %)) (exprs (second %))) v)))
(exprs (split [1 2 3 4]))
that gives me,
java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
Can anyone tell me what am i missing from the haskell code?
His full code listing is available here.
Clojure is an general purpose dynamic programming language. On the other hand, Haskell is a strictly typed programming language. In short, we can say it is an functional programming language. Since it is dynamic so it is very difficult or us to find the error.
Clojure or Haskell? Learn both; first Haskell then Clojure. Haskell is strongly typed and pure functional, but it doesn't have many code libraries to solve modern problems. That makes Haskell an ideal language to experiment and learn programming.
Rust is more reliably performant than Haskell, relying less on compiler magic and more on zero-cost abstractions. This emphasis means that the designers try to introduce as much programming convenience as possible where it won't involuntarily reduce performance. Rust's Iterators is an excellent example of this.
Python and Haskell have a strong type system, which means explicit conversions have to be done. However, while Python is dynamically typed, Haskell is statically typed. Python is a lot slower than Haskell.
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
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With