Haskell к Clojure

Я пробегаюсь через эту лекцию 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?

Его полный листинг кода доступен здесь.

8
задан Abel 15 December 2009 в 08:14
поделиться

2 ответа

Это тесно связано с реализацией 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 .

4
ответ дан 5 December 2019 в 20:16
поделиться

Исключение результаты из 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 
4
ответ дан 5 December 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: