Clojure PN (java.lang.ClassCastException)

Я использую Clojure для игры в гольф с кодом, цель которой — написать функцию, которая оценивает и возвращает значение из выражения польской нотации. Ниже мой код.

(require '[clojure.string :as s])
(defn p[e](
    (load-string (reduce (fn[x c] 
        (s/replace x #"([\+\-\*\/] (\(.*\) \d+|\d+ \d+))" "($0)")
    ) e (subvec (s/split e #"\d") 1)))))

Помните, что это код для гольфа (не предназначен для чтения).

Короче говоря, функция принимает строку, затем строка разбивается на вектор. Функция Reduce выполняет итерации по вектору и применяет выражение для n-1 элементов вектора. На выходе получается строка, которую Clojure должен иметь возможность оценить с помощью load-string.

Если я объявляю переменную с именем e со значением "+ 3 5", а затем запускаю только сокращение из функции, ожидается, что "(+ 3 5)" будет возвращено. Но когда я вызываю функцию как (p "+ 3 5"), я получаю следующую ошибку.

java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

Понятия не имею, что здесь происходит.


person Dan Prince    schedule 01.09.2013    source источник
comment
На самом деле я получаю следующее: ClassCastException java.lang.Long нельзя преобразовать в clojure.lang.IFn.   -  person Chiron    schedule 02.09.2013
comment
1. Я думаю, что выбрал бы Форт для этой задачи - готово. 2. Вы забыли реверс в RPN? 3. (defn rpn [& e](reduce #(if (fn? %2)(let [[l r & m]%](cons (%2 r l) m))(cons %2 %))[]e)) @learnclojure   -  person A. Webb    schedule 02.09.2013
comment
@A.Webb 1. Я изучу Форт. 2. Извините, я имел в виду ПН. Прошло некоторое время с тех пор, как я узнал об этом. Немного запутались в голове. 3. Вкусно! Я собираюсь разобрать это. Спасибо.   -  person Dan Prince    schedule 02.09.2013


Ответы (1)


Вы используете дополнительные круглые скобки после вектора defn args. Так должно быть:

(defn r[e]
  (load-string 
    (reduce 
      (fn[x c] 
        (s/replace x #"([\+\-\*\/] (\(.*\) \d+|\d+ \d+))" "($0)")) 
      e 
      (subvec (s/split e #"\d") 1))))

user=> (r "+ 3 5")
8
person Chiron    schedule 01.09.2013