2016-02-27 4 views
0

Мне нужно реализовать функцию, называемую Eval-математическая строкой в ​​Clojure, который принимает математическую строку в качестве входных данных и оценивает его: (eval-math-string "7+8/2") => 11Оценить математическую строку в Clojure

Так что я сумел распадаться выражение используя re-seq, и теперь я хочу оценить его с помощью Incanter. Однако у меня есть выражение типа ("7" "+" "8" "/" "2"), но для Incanter требуется выражение типа ($ = 7 + 8/2), где $ = - ключевое слово incanter. Как я могу передать список односимвольных строк в список, включая $ =, чтобы он выполнялся правильно. Если аргументы являются строками, функция не будет работать, но я не могу преобразовать числа +, *,/и т. Д., Поэтому я немного застрял.

Кто-нибудь знает, как я могу это сделать, или если есть лучший способ сделать это?

+0

Что случилось с '(str" ($ = "math-string") ")' где 'math-string' - ваш ввод? – jmargolisvt

+0

Вам нужно использовать Incanter? –

+0

@Piotrek Bzdyl: Нет, совсем нет, если вы знаете лучший способ. – Phylth

ответ

3

Ведун $= макрос just calls the infix-to-prefix function, поэтому все, что вам нужно сделать, это конвертировать список строк в список символов и цифр, а затем вызвать infix-to-prefix.

Я буду считать, что входной просто плоский список строк, каждая из которых представляет собой либо целое число (например, "7", "8", "2") или символ (например, "+", "/"). Если это предположение верно, то вы могли бы написать функцию преобразования, как это:

(defn convert [s] 
    (try 
    (Long/parseLong s) 
    (catch NumberFormatException _ 
     (symbol s)))) 

Пример:

(infix-to-prefix (map convert ["7" "+" "8" "/" "2"])) 

Конечно, если вы просто пишете макрос поверх $=, нет никакой необходимости называть infix-to-prefix, так как вы просто собираете список с $= в качестве первого элемента. Я буду считать, что у вас уже есть функция под названием math-split, который может превратить что-то вроде "7+8/2" в нечто вроде ["7" "+" "8" "/" "2"], в этом случае вы можете сделать это:

(defmacro eval-math-string [s] 
    `($= [email protected](map convert (math-split s)))) 

Пример:

(macroexpand-1 '(eval-math-string "7+8/2")) 
;=> (incanter.core/$= 7 + 8/2) 
Смежные вопросы