Во-первых, хотя SICP замечательный, я бы рекомендовал против него изучать Haskell. (#) Некоторые из трудностей в этом вопросе вытекают из этого.
В Lisp/Scheme 'function' рассматривается как часть кода, и рассмотрение функции просто означает изучение ее кода. В Haskell значение 'function' означает нечто более близкое к его математическому определению как карту из множества A в множество B. Так, например, в контексте Lisp имеет смысл сравнить две функции: просто сравните их код. (Но есть (x+y)^2
и x^2+2*x*y+y^2
разные функции?) В Haskell это зависит от того, существует ли конструктивная процедура определения равенства для класса функций, который вы рассматриваете.
Аналогично, как и в вашем вопросе, в Lisp/Scheme вы должны написать функцию «выводить», которая корректно отличает эти выражения, а только ошибки или возвращает мусор на произвольные входные данные. В системе типа Haskell это невозможно сделать (AFAIK), потому что, если вы думаете об этом, нет такой вещи, как дифференциация произвольного ввода: вы можете дифференцировать только выражение (или, возможно, более общий класс, но все же не все). Так как в ответ Нормана Рэмси, необходимо сначала определить тип «Expression» (или класс типа), что очень просто сделать, а затем записать функцию
derive :: Expression -> Expression
, что разбирает в Expression
с использованием шаблонов сопоставления конструкции (или что-то еще в зависимости от того, как были построены Expression
).
(#): Причина заключается в том, что SICP имеет совершенно иную философию, которая включает в себя использование нетипизированного языка программирования и обнадеживающую отсутствие различия между кодом и данными. Хотя есть некоторые достоинства в аргументе «code = data» (например, тот факт, что на архитектуре фон Неймана мы используем «все равно 0 и 1 в любом случае»), это не обязательно хороший способ рассуждать о проблемах или проблемах моделирования.(См. Philip Wadler's Why Calculating is Better than Scheming). Если вы хотите прочитать книгу Хаскелла с функциональным ароматом вместо Real World, возможно, лучше выбрать Haskell: The Craft of Functional Programming Саймона Томпсона или Ричарда Берда Introduction to Functional Programming using Haskell.
Как насчет оценки ваших данных об опыте (насколько я понимаю, это, в конечном счете, список)? –
Мне действительно не нужна функция eval; Я использовал символическое дифференцирование для испускания кода C. Если вы хотите написать одно и у вас проблемы, задайте вопрос :-) –