Ошибка при использовании функции применения в Clojure: не знаю, как создать ISeq из: java.lang.Long

Работаем над следующим примером в «Clojure в действии» (стр. 63):

(defn basic-item-total [price quantity] 
    (* price quantity))

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)]
     :post [(> % 1)]} 
    (apply f price quantity))

Оценка на REPL:

(with-line-item-conditions basic-item-total 20 1)

В результате возникает следующее исключение:

Don't know how to create ISeq from: java.lang.Long
  [Thrown class java.lang.IllegalArgumentException]

Похоже, что исключение генерируется после оценки процедуры применения.


person dtg    schedule 24.08.2012    source источник
comment
apply — это функция, а не макрос.   -  person amalloy    schedule 25.08.2012


Ответы (1)


Последний аргумент apply должен быть последовательностью аргументов. В вашем случае использование может выглядеть примерно так:

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)]
     :post [(> % 1)]} 
    (apply f [price quantity]))

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

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)]
     :post [(> % 1)]} 
    (f price quantity))
person Beyamor    schedule 24.08.2012
comment
Спасибо - теперь я вижу, что в случае применения макроса последовательность должна быть вектором. Это было неясно после прочтения описания после оценки (doc apply): Применяет fn f к списку аргументов, сформированному путем добавления промежуточных аргументов к args. - person dtg; 24.08.2012
comment
Да, некоторые строки документа могут быть довольно непрозрачными. Шпаргалка — отличное место для примеров использования. - person Beyamor; 24.08.2012