Главная » Просмотр файлов » John Harrison - Введение в функциональное программирование

John Harrison - Введение в функциональное программирование (1108517), страница 26

Файл №1108517 John Harrison - Введение в функциональное программирование (John Harrison - Введение в функциональное программирование) 26 страницаJohn Harrison - Введение в функциональное программирование (1108517) страница 262019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 26)

Предложите пример использования данного или подобного рекурсивногоисключения.108Глава 8. Эффективный ML8.3. Императивные возможности#exception Recurse of exn;;5. Напишите простую версию быстрой сортировки на массивах. Сначала массивразделяется на две части по некоторому элементу, затем на левой части ина правой рекурсивно вызывается sort. Какой рекурсивный вызов являетсяхвостовым? Сколько требуется памяти в худшем случае? Как с помощьюнебольшого изменения в коде добиться значительной оптимизации?6. Докажите, что обе версии rev, что мы упомянули, всегда дают одинаковыйрезультат.1098.3. Императивные возможностиГлава 8. Эффективный ML110Глава 9ПримерыКак мы говорили, ML изначально был спроектирован как метаязык дляавтоматизированного доказательства теорем.

Однако он пригоден и для многихдругих приложений, по большей части из области «символьных вычислений». В этойглаве мы дадим несколько характерных примеров использования ML. От читателя нетребуется досконального знания всех деталей, как, например, в случае приближениявещественных чисел, приведённом далее. Однако важно позапускать эти программы,выполнить упражнения. Поскольку нет лучшего способа почувствовать, как MLиспользуется в действительности.9.1Символьное дифференцированиеФраза «символьное вычисление» довольно неопределённа, но грубо говоря,она охватывает приложения занимающиеся не просто численными расчётами, аманипуляциями над математическими выражениями, в общем случае содержащимипеременные. Есть несколько успешных «систем компьютерной алгебры» таких какMaxima, Maple и Mathematica. Они могут выполнять полезные математическиеоперации: разложение многочленов на множители, дифференцирование иинтегрирование выражений и т.д.

Они также пригодны и для обычных вычислений.Мы покажем, как задачи такого рода могут быть решены с помощью ML.Мы выбрали символьное дифференцирование для нашего примера, потому чтодля него есть довольно простой и известный алгоритм. Читатель, возможно, знаком сdsin(x) = cos(x), а также с правиламипроизводными основных функций, например dxдифференцирования произведения и композиции функций. Поскольку каждыйможет систематически использовать эти правила для нахождения производных, товозможно и запрограммировать их на ML.9.1.1Термы первого порядкаМы будем допускать математические выражения в весьма общей форме.

Онимогут быть построены из переменных и констант, с использованием операторов.Операторы могут быть унарными, бинарными, тернарными, или, в общем случае,арности n. Это выражается с помощью следующего рекурсивного типа данных:1119.1. Символьное дифференцированиеГлава 9. Примеры#type term = Var of string| Const of string| Fn of string * (term list);;Type term defined.Например, выражение:sin(x + y)/cos(x − exp(y)) − ln(1 + x)представляется:Fn("-",[Fn("/",[Fn("sin",[Fn("+",[Var "x"; Var "y"])]);Fn("cos",[Fn("-",[Var "x"; Fn("exp",[Var "y"])])])]);Fn("ln",[Fn("+",[Const "1"; Var "x"])])]);;9.1.2ПечатьЧтение и запись выражений в сыром виде довольно неудобны.

Это общаяпроблема для всех систем символьных вычислений, и обычно интерфейссистемы содержит синтаксический анализатор (парсер) и систему ввода-вывода,позволяющую вводить и выводить данные в читаемой форме. Отложим покаподробное обсуждение синтаксического разбора, поскольку эта, сама по себе важнаятема, будет обсуждаться далее, а сейчас мы напишем простенькую систему выводадля наших выражений. Чтобы, по крайней мере, можно было видеть что происходит.Мы хотим, чтобы поддерживались обычные соглашения, как-то:• Переменные и константы записываются по их именам.• Обычные n-арные функции, выводятся в виде f (x1 , . .

. , xn ), т.е. записываетсяимя функции и рядом, в скобках список аргументов.• Инфиксные бинарные функции, такие как + записываются между своимиаргументами.• Скобки используются по необходимости.• В целях сокращения использования скобок, для инфиксных операторовопределён приоритет.Сначала мы объявим список инфиксных операторов – список пар из имениоператора и его приоритета.#let infixes = ["+",10; "-",10; "*",20; "/",20];;Использование списков для представления конечных частичных функцийявляется стандартной практикой. Они обычно называются ассоциативнымисписками и весьма распространены в функциональном программировании.1 Для тогочтобы конвертировать список в частичную функцию мы используем assoc:1Для более тяжеловесных приложений больше подойдут альтернативы, такие как хеш-таблицы,но для простых приложений, в которых списки не слишком длинны, решение в виде линейногосписка является простым и адекватным.112Глава 9. Примеры9.1.

Символьное дифференцирование#let rec assoc a ((x,y)::rest) = if a = x then y else assoc a rest;;Toplevel input:>let rec assoc a ((x,y)::rest) = if a = x then y else assoc a rest;;>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Warning: this matching is not exhaustive.assoc : ’a -> (’a * ’b) list -> ’b = <fun>Компилятор предупреждает нас - вычисление функции может прерваться, еслиподходящие данные не будут найдены в списке. Теперь мы можем определитьфункцию, возвращающую приоритет оператора:#let get_precedence s = assoc s infixes;;get_precedence : string -> int = <fun>#get_precedence "+";;- : int = 10#get_precedence "/";;- : int = 20#get_precedence "%";;Uncaught exception: Match_failure ("", 6544, 6601)Обратите внимание, если мы когда - либо изменим этот список операторов,то всякую функцию, вроде get_precedence, использующую его, потребуетсяпереопределить.

Это является основной причиной, по которой многие LISPпрограммисты предпочитают динамическое связывание. Множество инфиксныхоператоров можно сделать произвольно расширяемым, используя обращение поссылке:#let infixes = ref ["+",10; "-",10; "*",20; "/",20];;infixes : (string * int) list ref =ref ["+", 10; "-", 10; "*", 20; "/", 20]#let get_precedence s = assoc s (!infixes);;get_precedence : string -> int = <fun>#get_precedence "^";;Uncaught exception: Match_failure ("", 6544, 6601)#infixes := ("^",30)::(!infixes);;- : unit = ()#get_precedence "^";;- : int = 30Отметим, что по правилам вычисления в ML, разыменование указателяприменяется только после того, как get_precedence получает свои аргументы,и, следовательно, результаты во множестве операторов.

Мы также можем задатьфункцию, определяющую, является ли некоторая функция инфиксным оператором.Можно просто использовать get_precedence и смотреть сработала ли она:#let is_infix s =try get_precedence s; truewith _ -> false;;Альтернатива заключается в использовании общей функции can, котораяпроверяет успешность вычисления другой функции:1139.1.

Символьное дифференцированиеГлава 9. Примеры#let can f x = try f x; true with _ -> false;;can : (’a -> ’b) -> ’a -> bool = <fun>#let is_infix = can get_precedence;;is_infix : string -> bool = <fun>Мы будем использовать следующие функции из уже рассмотренных:#let hd(h::t) = h;;#let tl(h::t) = t;;#let rec length l = if l = [] then 0 else 1 + length(tl l);;Без дальнейших хлопот, вот функция для конвертации терма в строку.#let rec string_of_term prec =fun (Var s) -> s| (Const c) -> c| (Fn(f,args)) ->if length args = 2 & is_infix f thenlet prec’ = get_precedence f inlet s1 = string_of_term prec’ (hd args)and s2 = string_of_term prec’ (hd(tl args)) inlet ss = s1^" "^f^" "^s2 inif prec’ <= prec then "("^ss^")" else sselsef^"("^(string_of_terms args)^")"and string_of_terms t =match t with[] -> ""| [t] -> string_of_term 0 t| (h::t) -> (string_of_term 0 h)^","^(string_of_terms t);;Первый аргумент prec обозначает уровень приоритета оператора, для котороготекущее рассматриваемое выражение является непосредственным подтермом.

Такчто если текущее выражение имеет инфиксный оператор с некоторым приоритетом,то скобки необходимы, если приоритет этого оператора ниже prec. Например,если мы рассматриваем правую часть x ∗ (y + z). На самом деле, для болеенаглядной группировки мы используем скобки даже когда prec и приоритеттекущего оператора равны. В случае ассоциативных операторов, вроде + это неважно, но мы должны различать x − (y − z) и (x − y) − z. (Более усложнённаясхема могла бы учитывать ассоциативность каждого оператора.) Вторая, взаимнорекурсивная, функция string_of_terms используется для печати списка термовчерез запятую, как они идут в неинфиксной форме f (t1 , .

. . , tn ). Давайте посмотримэто в действии:114Глава 9. Примеры9.1. Символьное дифференцирование#let t =Fn("-",[Fn("/",[Fn("sin",[Fn("+",[Var "x"; Var "y"])]);Fn("cos",[Fn("-",[Var "x";Fn("exp",[Var "y"])])])]);Fn("ln",[Fn("+",[Const "1"; Var "x"])])]);;t : term =Fn("-",[Fn("/",[Fn ("sin", [Fn ("+", [Var "x"; Var "y"])]);Fn ("cos", [Fn ("-", [Var "x"; Fn ("exp", [Var "y"])])])]);Fn ("ln", [Fn ("+", [Const "1"; Var "x"])])])#string_of_term 0 t;;- : string = "sin(x + y) / cos(x - exp(y)) - ln(1 + x)"На самом деле, нам даже не требуется самостоятельно конвертировать терм встроку.

CAML Light позволяет нам настроить свою систему вывода. Это требуетнесколько специальных команд:##open "format";;#let print_term s =open_hvbox 0;print_string("‘"^(string_of_term 0 s)^"‘");close_box();;print_term : term -> unit = <fun>#install_printer "print_term";;- : unit = ()Почувствуйте разницу:#let t =Fn("-",[Fn("/",[Fn("sin",[Fn("+",[Var "x"; Var "y"])]);Fn("cos",[Fn("-",[Var "x";Fn("exp",[Var "y"])])])]);Fn("ln",[Fn("+",[Const "1"; Var "x"])])]);;t : term = ‘sin(x + y) / cos(x - exp(y)) - ln(1 + x)‘#let x = tx : term = ‘sin(x + y) / cos(x - exp(y)) - ln(1 + x)‘После того как новый принтер установлен, он будет использоваться всякий разпри печати типа term, даже если он представляет собой составной тип данных, как,например, кортеж:#(x,t);;- : term * term =‘sin(x + y) / cos(x - exp(y)) - ln(1 + x)‘,‘sin(x + y) / cos(x - exp(y)) - ln(1 + x)‘или список:#[x; t; x];;- : term list[‘sin(x + y)‘sin(x + y)‘sin(x + y)=/ cos(x - exp(y)) - ln(1 + x)‘;/ cos(x - exp(y)) - ln(1 + x)‘;/ cos(x - exp(y)) - ln(1 + x)‘]1159.1.

Символьное дифференцированиеГлава 9. ПримерыПодобная печать всё же довольно груба, поскольку большие выражения неразбиваются аккуратно на линии. Библиотека format, из которой мы использовалинесколько функций выше, предлагает лучшее решение. Вместо конвертациитерма в строку и печати, мы можем выполнить отдельные вызовы печати длякаждой его части, с помощью специальной функции, помогающей системе печатиразбивать строки. Многие из принципов, использующиеся в этой и подобныхсистемах форматированного вывода рассматриваются в Oppen (1980). Мы не будемрассматривать их в книге, за подробностями обращайтесь к руководству по CAML.29.1.3ДифференцированиеПерейдём теперь к довольно простой задаче нахождения производной отфункции.

Характеристики

Тип файла
PDF-файл
Размер
1,38 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6392
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее