2009-02-13 5 views
7

Я новичок Haskell, хотя имел предыдущий опыт работы с Lisp/Scheme. Сейчас я рассматриваю примеры из SICP и пытаюсь реализовать их в Haskell, чтобы получить больше практического опыта. В лекции 3b авторы представляют функцию для вычисления производных символически. Он содержит, среди прочего, следующие строки:Изучение внутренних функций Haskell

(define (deriv exp var) 
    (cond ((constant? exp var) 0) 
      ((same-var? exp var) 1) 
; ... 

Далее в лекции, еще некоторые функции определены:

(define (constant? exp var) 
    (and (atom? exp) 
     (not (eq? exp var)))) 

Есть ли способ сделать то же самое в Haskell, то есть проверить атомарность и символическая эквивалентность некоторой другой функции? Или более общий, каковы средства «разборки» функций в Haskell?

ответ

4

Примеры схем на самом деле не рассматривают функции схемы. Я недавно сделал некоторую символическую дифференциацию в Haskell по значениям следующего типа:

data Exp a = Lit a 
      | Exp a :*: Exp a 
      | Exp a :+: Exp a 
      | Var String 
    deriving Eq 

Вместо Распознающий с помощью atom? или eq?case вы используете (или другое сопоставление с образцом) и ==.

+0

Как насчет оценки ваших данных об опыте (насколько я понимаю, это, в конечном счете, список)? –

+0

Мне действительно не нужна функция eval; Я использовал символическое дифференцирование для испускания кода C. Если вы хотите написать одно и у вас проблемы, задайте вопрос :-) –

1

Я не думаю, что вы можете это сделать. Lisp - homoiconic, Haskell - нет.

Тем не менее, в дальнейшем Googling поднялся Liskell, который является (?) Интересным гибридом.

+1

Да, хотя я про гомоконичность. Тем не менее, мне не нужны функции, данные и сама программа, чтобы они были представлены таким же образом. Тот факт, что представление типов алгебраических данных отличается от представления программы, не ограничивает меня в их деконструировании. –

6

Во-первых, хотя 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.

Смежные вопросы