2014-11-03 3 views
26

У меня есть функция, которая занимает много лет и зарплату, а затем рекурсивно удваивает зарплату до тех пор, пока годы не исчерпаны. Тем не менее, я получаю эту ошибку:ClassCastException java.lang.Long нельзя отнести к clojure.lang.IFn

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

Кодекс

(defn calculate-salary 
    [years salary] 
    (if (= years 0) 
     (salary) 
     (calculate-salary (- years 1) (* salary 2)))) 

Я очень новой для Clojure, так что я уверен, что его что-то простое, но я просто не могу выясните это.

+1

Чтобы быть справедливым, все ниже правильно ответили, но я могу отметить только один, как принято. –

ответ

32

ошибка не должна быть слишком трудно разобраться: число используется, где ожидается функция.

Скобка в Clojure не является структурой группировки, они используются в основном для вызова вызовов функций. Если вы измените (salary) на salary, вы вернете номер, а не попытаетесь назвать его функцией без аргументов.

+3

Прямо на. Мне нужно освободиться от моего императивного наследия! –

+0

Aha спасибо за объяснение. Смысл круглых скобок мне также не был ясен. В качестве побочной заметки у меня была такая же ошибка, потому что я написал '(повторно (read))' вместо '(повторно читаемый)'. – Cilyan

3

Вы должны удалить скобки со всего salary в вашем состоянии, если:

(if (= years 0) 
     salary 
     (calculate-salary (- years 1) (* salary 2)) 

форма (f arg1 arg2 ..) попытки вызвать f как функцию с arg1, arg2 ... в качестве аргументов. Поэтому (salary) пытается вызвать salary (длинный) как функцию без аргументов, следовательно, ошибку.

5

Этот

(salary) 

является вызовом функции, но salary не функция - это число.

Решение не обернуть его в скобках: значение

(if (= years 0) salary (calculate-salary (- years 1) (* salary 2))) 
6

Поскольку вы новичок, я переписал вашу функцию, чтобы быть немного более идиоматичным. Кроме того, он использует recur, поэтому он не будет потреблять стек вызовов.

(defn calculate-salary 
    [years salary] 
    (if (zero? years) 
    salary 
    (recur (dec years) (* salary 2)))) 

Обратите внимание на использование нуля? предикат, повторялись, и Декабре

EDIT: опечаток и грамматических