Я пробегаюсь через эту лекцию haskell по, считают в обратном порядке игру, я не знаю haskell, но я заинтересован проблемой, я пытаюсь портировать его код на clojure.
это - застрявшая первая часть, должно быть что-то, что я не вхожу в 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)
У меня есть свое собственное разделение, учитывая 1 2 3 4, оно выкладывает,
(((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]))
это дает мне,
java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
Кто-либо может сказать мне, что я пропускаю из кода haskell?
Его полный листинг кода доступен здесь.
Это тесно связано с реализацией Haskell, насколько позволяет мне мой ограниченный функционал Haskell ....
(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)))
Хотя я не тестировал.
Что касается вашего сообщения об ошибке: я думаю, проблема в том, что вы не вызываете split
рекурсивно в exprs
. Тогда вы получите 1
, где ожидается последовательность ...
Случайное другое примечание: count
линейно во времени для последовательностей. Поскольку нам просто нужно знать, есть ли у нас более одного элемента, мы можем проверить значение (next s)
против nil
.
Исключение результаты из EXPR, называемых рекурсивно и в конечном итоге вызывают со списком целых чисел. Ваш код обрабатывает только список списков или список длин.
(exprs '(2 3 4))
приводит к остальной ветви отчета о том, что расширяется:
(map #(concat (exprs (first %)) (exprs (second %))) '(2 3 4))))
, который выходит на:
(concat (exprs (first 2)) (exprs (second 2)))
(concat (exprs (first 3)) (exprs (second 3)))
(concat (exprs (first 4)) (exprs (second 4)))
и (первых 2) броска:
java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer