<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=5.18.174.153&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=5.18.174.153&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/5.18.174.153"/>
		<updated>2026-04-23T09:48:55Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=45796</id>
		<title>Функциональное программирование</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=45796"/>
				<updated>2015-04-26T18:03:14Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.174.153: /* Аппликативный порядок редукции */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Кр1=&lt;br /&gt;
==Убрать все сокращения и расставить все скобки==&lt;br /&gt;
(λ a b . (λ c d e . e) a) (x y) y (λ f . x) y&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
Скобки ставятся по следующим правилам:&lt;br /&gt;
* тело абстракции заключается в скобки: λ x . M &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; λ x . (M)&lt;br /&gt;
* аппликация левоассоциативна: a b c d &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; ((a b) c) d&lt;br /&gt;
* сокращения раскрываются во вложенные лямбды (сразу с расставлением скобок): λ a b c . M &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; λ a . (λ b . (λ c . (M)))&lt;br /&gt;
Важно: тело абстракции забирает всё до конца той скобки, в которую заключена.&lt;br /&gt;
&lt;br /&gt;
Итого: ((((λ a . (λ b . ((λ c . (λ d . (λ e . (e)))) a))) (x y)) y) (λ f . (x))) y&lt;br /&gt;
&lt;br /&gt;
==Привести в нормальную форму==&lt;br /&gt;
&lt;br /&gt;
λ a b . a (λ c . b c) a (λ d . d) a&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
λ a . (λ b . y) (λ c . y (y (λ d . a a a)) (x x) a)&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
В нормальной форме нет редукций. Если нормальная форма существует, то её можно достичь при помощи редукций нормальным порядком, а аппликативным можно и не достичь.&lt;br /&gt;
&lt;br /&gt;
# Уже в нормальное форме, как ни странно&lt;br /&gt;
# λ a . y&lt;br /&gt;
&lt;br /&gt;
==Нормальный порядок редукции==&lt;br /&gt;
(λ a . y (y (y (λ b . a))) y) (x (x (x (λ c d . d) y)) x)&lt;br /&gt;
&lt;br /&gt;
[http://softoption.us/content/node/46 Здесь] про стратегии редуцирования с примерами и определениями.&lt;br /&gt;
&lt;br /&gt;
'''Нормальный порядок редуцирования''' {{---}} сначала раскрывается самый левый самый внешний редекс.&lt;br /&gt;
Пример не очень удачный, так в нём всего одна редукция, после которой получится: y (y (y (λ b . (x (x (x (λ c d . d) y)) x)))) y&lt;br /&gt;
&lt;br /&gt;
Более показательные и содержательные примеры (во всех случаях одна редукция будет произведена):&lt;br /&gt;
* (λ a . a) ((λ x . x) y) &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; (λ x . x) y&lt;br /&gt;
* x (λ a . ((λ x . x) y) ((λ z . z) y)) &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; x (λ a . y ((λ z . z) y))&lt;br /&gt;
&lt;br /&gt;
==Аппликативный порядок редукции==&lt;br /&gt;
[http://pv.bstu.ru/flp/fpLectures.pdf Здесь] ещё про стратегии редуцирования, но немного другим языком (может быть, кому-то более понятным).&lt;br /&gt;
&lt;br /&gt;
'''Аппликативный порядок редуцирования''' {{---}} первым делом редуцируем самый левый самый глубокий терм. То есть сначала упрощаем &amp;quot;аргументы&amp;quot; аппликации.&lt;br /&gt;
&lt;br /&gt;
Те же примеры (во всех случаях одна редукция будет произведена):&lt;br /&gt;
* (λ a . a) ((λ x . x) y) &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; (λ a . a) y&lt;br /&gt;
* x (λ a . ((λ x . x) y) ((λ z . z) y)) &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt; x (λ a . ((λ x . x) y) y)&lt;br /&gt;
Ещё один для разнообразия:&lt;br /&gt;
((λ x . y) (λ z . t)) ((λ a b c . a b c ((λ s . t) y) (λ t . x) u) (λ x . x)) ((λ x . x x) z) &amp;lt;tex&amp;gt; \Rightarrow &amp;lt;/tex&amp;gt;&lt;br /&gt;
((λ x . y) (λ z . t)) ((λ a b c . a b c ((λ s . t) y) (λ t . x) u) (λ x . x)) (z z)&lt;br /&gt;
&lt;br /&gt;
==Выписать систему уравнений типизации==&lt;br /&gt;
(λ a . a a) (λ b c . c)&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
Сначала надо дать типы всем термам и подтермам, раздавая каждый раз новые буквы новым переменным и термам. А потом связать эти буквы по следующим правилам:&lt;br /&gt;
* если у нас абстракция (λ x . M) :: T0, x :: T1, M :: T2, то добавляем в систему T0 = T1 -&amp;gt; T2,&lt;br /&gt;
* если имеем аппликацию (M N) :: T0, M :: T1, N :: T2, то добавляем T1 = T2 -&amp;gt; T0&lt;br /&gt;
* если у нас переменная в теле абстракции встречается несколько раз и мы раздаём каждый раз ей новые буквы, то надо будет потом приравнять типы в аргументе абстракции и внутри её тела.&lt;br /&gt;
&lt;br /&gt;
Итого:&lt;br /&gt;
&lt;br /&gt;
(λ a . a a) (λ b c . c) :: A&lt;br /&gt;
&lt;br /&gt;
(λ a . a a) :: B, (λ b c . c) :: C&lt;br /&gt;
&lt;br /&gt;
a :: D, (a a) :: E&lt;br /&gt;
&lt;br /&gt;
первая и вторая буквы &amp;quot;a&amp;quot; в E {{---}} a :: F, a :: G&lt;br /&gt;
&lt;br /&gt;
Можем сразу расписать часть системы уравнений:&lt;br /&gt;
&lt;br /&gt;
B = C -&amp;gt; A&lt;br /&gt;
&lt;br /&gt;
B = D -&amp;gt; E&lt;br /&gt;
&lt;br /&gt;
F = G -&amp;gt; E&lt;br /&gt;
&lt;br /&gt;
D = F&lt;br /&gt;
&lt;br /&gt;
D = G&lt;br /&gt;
&lt;br /&gt;
Теперь расписываем терм с типом C (раскрыв сокращения для начала): (λ b . (λ c . c)) :: С&lt;br /&gt;
&lt;br /&gt;
b :: H, (λ c . c) :: I&lt;br /&gt;
&lt;br /&gt;
c :: J, c :: K&lt;br /&gt;
&lt;br /&gt;
И добавляем уравнения:&lt;br /&gt;
&lt;br /&gt;
C = H -&amp;gt; I&lt;br /&gt;
&lt;br /&gt;
I = J -&amp;gt; K&lt;br /&gt;
&lt;br /&gt;
J = K&lt;br /&gt;
&lt;br /&gt;
==Кодирование по Чёрчу==&lt;br /&gt;
Выписать кайнды конструкторов типов, выписать типы конструкторов, закодировать по Чёрчу:&lt;br /&gt;
&lt;br /&gt;
data Policeman a = Doctor a | Mice&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
data Tree a b c = Frog c | Pip (Tree a b c)&lt;br /&gt;
&lt;br /&gt;
Этого задания не было в первой кр, поэтому оно будет расписано во второй. Вместо него была система уравнений типов чуть более адовая, чем в прошлом примере.&lt;br /&gt;
&lt;br /&gt;
=Кр2=&lt;br /&gt;
==Фотки==&lt;br /&gt;
* [https://pp.vk.me/c625522/v625522095/bb5e/DJapJCj1SGE.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625522/v625522095/bb68/OwKD9uzHoA8.jpg]&lt;br /&gt;
* [https://pp.vk.me/c622826/v622826349/bfc5/atAYCtU1zZI.jpg]&lt;br /&gt;
* [https://pp.vk.me/c622826/v622826349/bfcf/FvqIHdp-Dmw.jpg]&lt;br /&gt;
* [https://pp.vk.me/c622826/v622826349/bfd9/uMwr0U0rfrI.jpg]&lt;br /&gt;
* [https://pp.vk.me/c622820/v622820834/92be/d-3b04La1JQ.jpg]&lt;br /&gt;
* [https://pp.vk.me/c622820/v622820834/92c8/UUa3Pn9hASM.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625826/v625826822/9142/uc_MHBKBJv4.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625826/v625826822/914c/-bzSn1_q6YI.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625826/v625826822/9156/gULmjYE46fY.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625826/v625826822/9160/8s4as7q7uKA.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625826/v625826822/916a/2US214bNwv0.jpg]&lt;br /&gt;
* [https://pp.vk.me/c625826/v625826822/9174/QRhQIqwNX5Q.jpg]&lt;br /&gt;
&lt;br /&gt;
Разбор будет по фоткам 3, 4, 5 (остальные задания аналогичны):&lt;br /&gt;
&lt;br /&gt;
== N1. Порядок редуцирования ==&lt;br /&gt;
См. прошлую кр&lt;br /&gt;
&lt;br /&gt;
== E0. Определить примитивные конструкции == &lt;br /&gt;
&lt;br /&gt;
 pair = \ x y p . p x y&lt;br /&gt;
 fst  = \ r . r (\ x y . x)&lt;br /&gt;
 snd  = \ r . r (\ x y . y)&lt;br /&gt;
 fix  = \ f . (\ x . f (x x)) (\ x . f (x x))&lt;br /&gt;
&lt;br /&gt;
Легко проверить, что fst (pair a b) = a, подставив и сделав редукции.&lt;br /&gt;
&lt;br /&gt;
== E1. Превратить let-биндинги в один большой лямбда-терм. ==&lt;br /&gt;
&lt;br /&gt;
Конструкция &lt;br /&gt;
&lt;br /&gt;
 '''let''' x = z '''in''' y&lt;br /&gt;
&lt;br /&gt;
превращается в &lt;br /&gt;
&lt;br /&gt;
(\x . y) z &lt;br /&gt;
&lt;br /&gt;
А пример просто превратится в &lt;br /&gt;
&lt;br /&gt;
(\foo. [main]) [foo]&lt;br /&gt;
&lt;br /&gt;
где [foo] {{---}} тело foo, [main] {{---}} тело main.&lt;br /&gt;
&lt;br /&gt;
== E2. let-биндинги, но с возможной взаимной рекурсией ==&lt;br /&gt;
&lt;br /&gt;
foo = foo ((\ a . bar) foo)&lt;br /&gt;
&lt;br /&gt;
bar = (\ a . y) y (\ b . y)&lt;br /&gt;
&lt;br /&gt;
main = (\ a . foo (a z) (y y)) y&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
&amp;lt;font color=magenta&amp;gt; '''Осторожно! Магия''' &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расписывать формальный алгоритм довольно нудно и неприятно, поэтому здесь объяснение того, что происходит, а на примере должно быть понятно.&lt;br /&gt;
&lt;br /&gt;
Сначала по каждому терму из условия надо составить терм с таким же именем, только штрихованный. В нём мы будем использовать первые буквы остальных термов. Фиксируем порядок аргументов, например для foo' это будет f b m. Тогда у всех остальных термов будет циклический порядок. То есть для bar' будет b m f, а для main' {{---}} m f b.&lt;br /&gt;
&lt;br /&gt;
Теперь пишем foo'. Сначала используем fix. Потом абстракцию, аргументами которой является нужный набор из циклических перестановок (см. соответствие выше), а телом абстракции является тело foo с изменениями. Если встречается имя терма из задания, то надо его заменить на нужный циклический порядок. И если имена первых букв по каким-то причинам не подходят (коллизятся со связанными переменными), то надо более удачные имена этим переменным придумать.&lt;br /&gt;
&lt;br /&gt;
Итого, после преобразований:&lt;br /&gt;
&lt;br /&gt;
 foo'  = fix (\ f b m . f b m ((\ a . b m f) (f b m)))&lt;br /&gt;
 bar'  = fix (\ b m f . (\ a . y) y (\ b . y))&lt;br /&gt;
 main' = fix (\ m f b . (\ a . f b m (a z) (y y)) y)&lt;br /&gt;
&lt;br /&gt;
Результирующий терм выглядит как вызов штрихованной функции в нужной циклической перестановке:&lt;br /&gt;
&lt;br /&gt;
 main = main' foo' bar'&lt;br /&gt;
&lt;br /&gt;
Но так как в этом задании дополнительные термы использовать нельзя, то main', foo', bar' надо проинлайнить в main.&lt;br /&gt;
&lt;br /&gt;
== N2. Раскрыть, как в E1 и нормализовать ==&lt;br /&gt;
&lt;br /&gt;
В общем, в задании всё сказано. Надо превратить в один большой терм как в E1, а затем нормализовать, как в задании из первой кр.&lt;br /&gt;
&lt;br /&gt;
== S1. Расписать систему уравнений типов ==&lt;br /&gt;
&lt;br /&gt;
Как в первой кр.&lt;br /&gt;
&lt;br /&gt;
== TP1. Убрать сокращения и расставить скобки ==&lt;br /&gt;
&lt;br /&gt;
Именно это и требуется сделать. Разве что там вместо тела абстракции расписан её тип. А (-&amp;gt;) в типе в отличие от аппликации правоассоциативна, то есть в &lt;br /&gt;
&lt;br /&gt;
a -&amp;gt; b -&amp;gt; c&lt;br /&gt;
&lt;br /&gt;
скобки ставятся следующим образом:&lt;br /&gt;
&lt;br /&gt;
a -&amp;gt; (b -&amp;gt; c)&lt;br /&gt;
&lt;br /&gt;
Итого:&lt;br /&gt;
* дано: (\ a b . b -&amp;gt; b -&amp;gt; a) x&lt;br /&gt;
* получается: (\ a . (\ b . b -&amp;gt; (b -&amp;gt; a))) x // вроде бы тут как раз весь тип внутри не надо заключать в скобки&lt;br /&gt;
&lt;br /&gt;
== TF1. Составить терм по типу ==&lt;br /&gt;
&lt;br /&gt;
Тут надо пользоваться логикой. Вроде бы во всех примерах можно решить методом пристального взгляда. Мотивация: чтобы решение системы уравнений типов совпадало с полученным типом. Но в некоторых случаях довольно трудно (или даже невозможно) придумать терм по типу, например здесь не придумывается:&lt;br /&gt;
&lt;br /&gt;
(a -&amp;gt; b) -&amp;gt; b -&amp;gt; a&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
&lt;br /&gt;
Дано: forall a b c . (b -&amp;gt; c -&amp;gt; a) -&amp;gt; (c -&amp;gt; b) -&amp;gt; c -&amp;gt; a&lt;br /&gt;
&lt;br /&gt;
Ответ: \f g c . f (g c) c&lt;br /&gt;
&lt;br /&gt;
== A1. Закодировать типы по Чёрчу (без взаимной рекурсии) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  '''data''' Doctor a = Minute a | Maybe a a a&lt;br /&gt;
  '''data''' Hour a b = Hour (Hour b b) (Doctor a) (Doctor b) | Roll b (Doctor a)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
У каждого типа есть &amp;lt;tex&amp;gt; N \geqslant 1&amp;lt;/tex&amp;gt; конструктов, а у каждого конструктора есть &amp;lt;tex&amp;gt; K \geqslant 0 &amp;lt;/tex&amp;gt; аргументов. &lt;br /&gt;
&lt;br /&gt;
Фиксируем тип с &amp;lt;tex&amp;gt; N &amp;lt;/tex&amp;gt; конструкторами. Каждый конструктор &amp;lt;tex&amp;gt; C_i &amp;lt;/tex&amp;gt; этого типа превращается в абстракцию, в которой сначала идут &amp;lt;tex&amp;gt; K_i &amp;lt;/tex&amp;gt; переменных {{---}} аргументы конструктора, а потом &amp;lt;tex&amp;gt; N &amp;lt;/tex&amp;gt; переменных, отвечающих конструкторам. В теле просто выбирается нужный конструктор и применяется ко всем аргументам.&lt;br /&gt;
&lt;br /&gt;
caseTypeName тоже является абстракцией, которая принимает сначала одну переменную, которая &amp;quot;выбирает&amp;quot; нужный конструктор, затем набор переменных в количестве числа конструкторов. В теле просто применяется первая переменная ко всем остальным.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- сначала Doctor &amp;lt;/font&amp;gt;&lt;br /&gt;
  Minute = \ a . \ x y . x a&lt;br /&gt;
  Maybe  = \ a b c . \ x y . y a b c&lt;br /&gt;
  caseDoctor = \ p . \ x y . p x y&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- теперь Hour &amp;lt;/font&amp;gt;&lt;br /&gt;
  Hour = \ a b c . \ x y . x a b c&lt;br /&gt;
  Roll = \ a b . \ x y . y a b&lt;br /&gt;
  caseHour = \ p . \ x y . p x y&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Интересное наблюдение: переменная p в case является как раз нужным конструктором, в котором уже подставлены все аргументы этого конструктора.&lt;br /&gt;
&lt;br /&gt;
== A2. Закодировать типы по Чёрчу (с взаимной рекурсией) ==&lt;br /&gt;
&lt;br /&gt;
 '''data''' Return a b = List (Return b a) (Return b a) b | Roll (Return a a) (Return a a) (Mice a)&lt;br /&gt;
 '''data''' Mice a = Bucket (Mice a) (Return a a) | Haystack (Mice a) a&lt;br /&gt;
&lt;br /&gt;
=== Решение ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=magenta&amp;gt; '''Магия как в E2!''' &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Опять делаем соотвествие между TypeName и TypeName'. Чтобы написать TypeName', необходимо преобразовать объявление дататипов по следующим правилам:&lt;br /&gt;
* сначала идёт mu (это как fix, только для типов),&lt;br /&gt;
* потом какая-нибудь уникальная буква для типа (например x для Return и y для Mice),&lt;br /&gt;
* после точки абстракция, которая сначала принимает в качестве аргумента другую уникальную букву, а затем аргументами параметры типа,&lt;br /&gt;
* T1 | T2 заменяется на T1 + T2,&lt;br /&gt;
* T1 T2 заменяется на T1 &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; T2,&lt;br /&gt;
* параметры типа оставляем как есть,&lt;br /&gt;
* если в конструкторе идёт наш тип, то пишем нашу уникальную букву, а затем уникальную букву другого типа, а если другой типа {{---}} наоборот; после чего параметры конструктора,&lt;br /&gt;
* если тип не наш и не буковка параметр датайпа, и не принимает параметров (например Nothing), то пишем 1 вместо неё.&lt;br /&gt;
&lt;br /&gt;
 Return' = mu x . \ y . \ a b . (x y b a) &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; (x y b a) &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; b + (x y a a) &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; (x y a a) &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; (y x a)&lt;br /&gt;
 Mice'   = mu y . \ x . \ a . (y x a) &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; (x y a a) | (y x a) &amp;lt;tex&amp;gt; \times &amp;lt;/tex&amp;gt; a&lt;br /&gt;
&lt;br /&gt;
После этого пишем ответ:&lt;br /&gt;
&lt;br /&gt;
 Return = Return' Mice'&lt;br /&gt;
 Mice   = Mice' Return'&lt;br /&gt;
&lt;br /&gt;
== H1. Написать Haskell-код какой-нибудь структуру данных ==&lt;br /&gt;
&lt;br /&gt;
* [[АВЛ-дерево]]: [http://pastie.org/private/qbiu60aetjm9zrpqzrow ссылка на pastie]&lt;br /&gt;
*: почему я не знал Haskell, когда это дерево было в лабе по дискретке на первом курсе? ;( просто списывается с конспекта один в один...&lt;br /&gt;
* [[Квадродеревья | Квадродерево]]: [http://pastie.org/private/sf1vdmrpe7ifvqgdongwq ссылка на pastie]&lt;br /&gt;
*: не совсем то, что требует Ян, но я пока не распарсил то, что он требует; возможно, более правильная версия появится позже&lt;br /&gt;
&lt;br /&gt;
=Кр3=&lt;br /&gt;
===ITMOPrelude===&lt;br /&gt;
#gromakovsky&lt;br /&gt;
#* [https://github.com/gromakovsky/haskell-course-ru/blob/master/ITMOPrelude/Primitive.hs Primitive.hs]&lt;br /&gt;
#* [https://github.com/gromakovsky/haskell-course-ru/blob/master/ITMOPrelude/List.hs List.hs]&lt;br /&gt;
# yakupov&lt;br /&gt;
#* [https://github.com/yakupov/Haskell_lab/blob/master/ITMOPrelude/Primitive.hs Primitive.hs]&lt;br /&gt;
#* [https://github.com/yakupov/Haskell_lab/blob/master/ITMOPrelude/List.hs List.hs]&lt;br /&gt;
# itanf&lt;br /&gt;
#* [https://github.com/itanf/ITMO-Training-FunctionalProgramming/blob/master/ITMOPrelude/Primitive.hs Primitive.hs]&lt;br /&gt;
#* [https://github.com/itanf/ITMO-Training-FunctionalProgramming/blob/master/ITMOPrelude/List.hs List.hs]&lt;br /&gt;
==Натуральные числа==&lt;br /&gt;
 data Nat = Zero | Succ Nat deriving (Show,Read) &amp;lt;font color=green&amp;gt;-- Определение натуральных чисел&amp;lt;/font&amp;gt;&lt;br /&gt;
 natZero = Zero     &amp;lt;font color=green&amp;gt;-- 0&amp;lt;/font&amp;gt;&lt;br /&gt;
 natOne = Succ Zero &amp;lt;font color=green&amp;gt;-- 1&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 natCmp :: Nat -&amp;gt; Nat -&amp;gt; Tri  &amp;lt;font color=green&amp;gt;-- Сравнивает два натуральных числа&amp;lt;/font&amp;gt;&lt;br /&gt;
 natCmp Zero Zero = EQ&lt;br /&gt;
 natCmp Zero (Succ _) = LT&lt;br /&gt;
 natCmp (Succ _) Zero = GT&lt;br /&gt;
 natCmp (Succ n) (Succ m) = natCmp n m&lt;br /&gt;
 &lt;br /&gt;
 natEq :: Nat -&amp;gt; Nat -&amp;gt; Bool  &amp;lt;font color=green&amp;gt;-- n совпадает с m&amp;lt;/font&amp;gt;&lt;br /&gt;
 natEq Zero     Zero     = True&lt;br /&gt;
 natEq Zero     (Succ _) = False&lt;br /&gt;
 natEq (Succ _) Zero     = False&lt;br /&gt;
 natEq (Succ n) (Succ m) = natEq n m&lt;br /&gt;
 &lt;br /&gt;
 natLt :: Nat -&amp;gt; Nat -&amp;gt; Bool  &amp;lt;font color=green&amp;gt;-- n меньше m&amp;lt;/font&amp;gt;&lt;br /&gt;
 natLt Zero     Zero     = False&lt;br /&gt;
 natLt Zero     (Succ m) = True&lt;br /&gt;
 natLt (Succ n) Zero     = False&lt;br /&gt;
 natLt (Succ n) (Succ m) = natLt n m&lt;br /&gt;
 &lt;br /&gt;
 infixl 6 +.  &amp;lt;font color=green&amp;gt;-- Сложение для натуральных чисел&amp;lt;/font&amp;gt;&lt;br /&gt;
 (+.) :: Nat -&amp;gt; Nat -&amp;gt; Nat&lt;br /&gt;
 Zero     +. m = m&lt;br /&gt;
 (Succ n) +. m = Succ (n +. m)&lt;br /&gt;
 &lt;br /&gt;
 infixl 6 -. &amp;lt;font color=green&amp;gt;-- Вычитание для натуральных чисел&amp;lt;/font&amp;gt;&lt;br /&gt;
 (-.) :: Nat -&amp;gt; Nat -&amp;gt; Nat&lt;br /&gt;
 Zero -. _ = Zero&lt;br /&gt;
 n -. Zero = n&lt;br /&gt;
 (Succ n) -. (Succ m) = n -. m&lt;br /&gt;
 &lt;br /&gt;
 infixl 7 *. &amp;lt;font color=green&amp;gt;-- Умножение для натуральных чисел&amp;lt;/font&amp;gt;&lt;br /&gt;
 (*.) :: Nat -&amp;gt; Nat -&amp;gt; Nat&lt;br /&gt;
 Zero     *. m = Zero&lt;br /&gt;
 (Succ n) *. m = m +. (n *. m)&lt;br /&gt;
 &lt;br /&gt;
 natDivMod :: Nat -&amp;gt; Nat -&amp;gt; Pair Nat Nat &amp;lt;font color=green&amp;gt;-- Целое и остаток от деления n на m&amp;lt;/font&amp;gt;&lt;br /&gt;
 natDivMod n m =&lt;br /&gt;
     if (n natLt m)&lt;br /&gt;
        then Pair Zero n&lt;br /&gt;
        else Pair (Succ div) mod where Pair div mod = ((n -. m) natDivMod m)&lt;br /&gt;
 &lt;br /&gt;
 natDiv n = fst . natDivMod n &amp;lt;font color=green&amp;gt;-- Целое&amp;lt;/font&amp;gt;&lt;br /&gt;
 natMod n = snd . natDivMod n &amp;lt;font color=green&amp;gt;-- Остаток&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Целые числа==&lt;br /&gt;
 data Int = Plus Nat | Minus Nat deriving (Show,Read)&lt;br /&gt;
 &lt;br /&gt;
 intZero   = Plus Zero&lt;br /&gt;
 intOne    = Plus (Succ Zero)&lt;br /&gt;
 intNegOne = Minus (Succ Zero)&lt;br /&gt;
 &lt;br /&gt;
 intNeg :: Int -&amp;gt; Int&lt;br /&gt;
 intNeg (Plus x) = Minus x&lt;br /&gt;
 intNeg (Minus x) = Plus x&lt;br /&gt;
 &lt;br /&gt;
 intCmp :: Int -&amp;gt; Int -&amp;gt; Tri&lt;br /&gt;
 intCmp (Plus Zero) (Minus Zero) = EQ&lt;br /&gt;
 intCmp (Minus Zero) (Plus Zero) = EQ&lt;br /&gt;
 intCmp (Plus Zero) (Minus (Succ x)) = GT&lt;br /&gt;
 intCmp (Minus Zero) (Plus (Succ x)) = LT&lt;br /&gt;
 intCmp (Plus (Succ x)) (Minus Zero) = GT&lt;br /&gt;
 intCmp (Minus (Succ x)) (Plus Zero) = LT&lt;br /&gt;
 intCmp (Plus x) (Plus y) = natCmp x y&lt;br /&gt;
 intCmp (Minus x) (Minus y) = natCmp y x&lt;br /&gt;
 &lt;br /&gt;
 intEq :: Int -&amp;gt; Int -&amp;gt; Bool&lt;br /&gt;
 intEq (Plus Zero) (Minus Zero) = True&lt;br /&gt;
 intEq (Minus Zero) (Plus Zero) = True&lt;br /&gt;
 intEq (Plus Zero) (Minus (Succ x)) = False&lt;br /&gt;
 intEq (Minus Zero) (Plus (Succ x)) = False&lt;br /&gt;
 intEq (Plus (Succ x)) (Minus Zero) = False&lt;br /&gt;
 intEq (Minus (Succ x)) (Plus Zero) = False&lt;br /&gt;
 intEq (Plus x) (Plus y) = natEq x y&lt;br /&gt;
 intEq (Minus x) (Minus y) = natEq x y&lt;br /&gt;
 &lt;br /&gt;
 intLt :: Int -&amp;gt; Int -&amp;gt; Bool&lt;br /&gt;
 intLt (Plus Zero) (Minus Zero) = False&lt;br /&gt;
 intLt (Minus Zero) (Plus Zero) = False&lt;br /&gt;
 intLt (Plus Zero) (Minus (Succ x)) = False&lt;br /&gt;
 intLt (Minus Zero) (Plus (Succ x)) = True&lt;br /&gt;
 intLt (Plus (Succ x)) (Minus Zero) = False&lt;br /&gt;
 intLt (Minus (Succ x)) (Plus Zero) = True&lt;br /&gt;
 intLt (Plus x) (Plus y) = natLt x y&lt;br /&gt;
 intLt (Minus x) (Minus y) = natLt y x&lt;br /&gt;
 &lt;br /&gt;
 infixl 6 .+., .-.&lt;br /&gt;
 (.+.) :: Int -&amp;gt; Int -&amp;gt; Int&lt;br /&gt;
 (Plus m) .+. (Plus n) = Plus (m +. n)&lt;br /&gt;
 (Minus m) .+. (Minus n) = Minus (m +. n)&lt;br /&gt;
 (Plus (Succ m)) .+. (Minus (Succ n)) = (Plus m) .+. (Minus n)&lt;br /&gt;
 (Minus (Succ m)) .+. (Plus (Succ n)) = (Plus m) .+. (Minus n)&lt;br /&gt;
 x .+. (Plus Zero) = x&lt;br /&gt;
 x .+. (Minus Zero) = x&lt;br /&gt;
 (Plus Zero) .+. y = y&lt;br /&gt;
 (Minus Zero) .+. y = y&lt;br /&gt;
 &lt;br /&gt;
 (.-.) :: Int -&amp;gt; Int -&amp;gt; Int&lt;br /&gt;
 n .-. m = n .+. (intNeg m)&lt;br /&gt;
 &lt;br /&gt;
 infixl 7 .*.&lt;br /&gt;
 (.*.) :: Int -&amp;gt; Int -&amp;gt; Int&lt;br /&gt;
 (Plus m) .*. (Plus n) = Plus (m *. n)&lt;br /&gt;
 (Minus m) .*. (Minus n) = Plus (m *. n)&lt;br /&gt;
 (Plus m) .*. (Minus n) = Minus (m *. n)&lt;br /&gt;
 (Minus m) .*. (Plus n) = Minus (m *. n)&lt;br /&gt;
&lt;br /&gt;
==Рациональные числа==&lt;br /&gt;
 data Rat = Rat Int Nat&lt;br /&gt;
 &lt;br /&gt;
 ratNeg :: Rat -&amp;gt; Rat&lt;br /&gt;
 ratNeg (Rat x y) = Rat (intNeg x) y&lt;br /&gt;
 &lt;br /&gt;
 ratInv :: Rat -&amp;gt; Rat&lt;br /&gt;
 ratInv (Rat (Plus x) y) = Rat (Plus y) x&lt;br /&gt;
 ratInv (Rat (Minus x) y) = Rat (Minus y) x&lt;br /&gt;
 &lt;br /&gt;
 ratCmp :: Rat -&amp;gt; Rat -&amp;gt; Tri&lt;br /&gt;
 ratCmp (Rat a b) (Rat c d) = intCmp (a .*. (Plus d)) (c .*. (Plus b))&lt;br /&gt;
 &lt;br /&gt;
 ratEq :: Rat -&amp;gt; Rat -&amp;gt; Bool&lt;br /&gt;
 ratEq (Rat a b) (Rat c d) = intEq (a .*. (Plus d)) (c .*. (Plus b))&lt;br /&gt;
 &lt;br /&gt;
 ratLt :: Rat -&amp;gt; Rat -&amp;gt; Bool&lt;br /&gt;
 ratLt (Rat a b) (Rat c d) = intEq (a .*. (Plus d)) (c .*. (Plus b))&lt;br /&gt;
 &lt;br /&gt;
 internalRatPlus :: Rat -&amp;gt; Rat -&amp;gt; Rat&lt;br /&gt;
 internalRatPlus (Rat a b) (Rat c d) = Rat ((a .*. (Plus d)) .+. (c .*. (Plus b))) (b *. d)&lt;br /&gt;
 &lt;br /&gt;
 internalRatShorten :: Rat -&amp;gt; Rat&lt;br /&gt;
 internalRatShorten (Rat (Plus a) b) = Rat (Plus (a /. (gcd a b))) (b /. (gcd a b))&lt;br /&gt;
 internalRatShorten (Rat (Minus a) b) = Rat (Minus (a /. (gcd a b))) (b /. (gcd a b))&lt;br /&gt;
 &lt;br /&gt;
 infixl 7 %+, %-&lt;br /&gt;
 (%+) :: Rat -&amp;gt; Rat -&amp;gt; Rat&lt;br /&gt;
 n %+ m = internalRatShorten (internalRatPlus n m)&lt;br /&gt;
 &lt;br /&gt;
 (%-) :: Rat -&amp;gt; Rat -&amp;gt; Rat&lt;br /&gt;
 n %- m = n %+ (ratNeg m)&lt;br /&gt;
 &lt;br /&gt;
 infixl 7 %*, %/&lt;br /&gt;
 (%*) :: Rat -&amp;gt; Rat -&amp;gt; Rat&lt;br /&gt;
 (Rat a b) %* (Rat c d) = Rat (a .*. c) (b *. d)&lt;br /&gt;
 &lt;br /&gt;
 (%/) :: Rat -&amp;gt; Rat -&amp;gt; Rat&lt;br /&gt;
 n %/ m = n %* (ratInv m)&lt;br /&gt;
&lt;br /&gt;
==GCD==&lt;br /&gt;
&lt;br /&gt;
'''Тут я не уверен, можем ли использовать ''natMod'' или надо дополнительно реализовывать её.&amp;lt;br/&amp;gt;Ещё мы вроде бы не можем использовать дополнительные функции!'''&lt;br /&gt;
&lt;br /&gt;
 gcd :: Nat -&amp;gt; Nat -&amp;gt; Nat&lt;br /&gt;
 gcd n Zero = n&lt;br /&gt;
 gcd n m = gcd m (natMod n m)&lt;br /&gt;
&lt;br /&gt;
==Метод Ньютона==&lt;br /&gt;
==subsequences==&lt;br /&gt;
 subsequences :: List a -&amp;gt; List (List a)&lt;br /&gt;
 subsequences Nil = Cons Nil Nil&lt;br /&gt;
 subsequences xs = (subseqtoend xs) ++ (subseqtoend (init xs))&lt;br /&gt;
 	where&lt;br /&gt;
 	subseqtoend :: List a -&amp;gt; List (List a)&lt;br /&gt;
 	subseqtoend Nil = Nil&lt;br /&gt;
 	subseqtoend (Cons x xs) = (Cons (Cons x xs) (subseqtoend(xs)))&lt;br /&gt;
&lt;br /&gt;
==permutations==&lt;br /&gt;
 permutations :: List a -&amp;gt; List (List a)&lt;br /&gt;
 permutations Nil = Nil&lt;br /&gt;
 permutations (Cons x Nil) = (Cons (Cons x Nil) Nil)&lt;br /&gt;
 permutations (Cons x xs) = insertAtEveryPosForList (permutations xs) x&lt;br /&gt;
 	where&lt;br /&gt;
 	insertAtEveryPos :: List a -&amp;gt; a -&amp;gt; Nat -&amp;gt; List (List a)&lt;br /&gt;
 	insertAtEveryPos str elem Zero = Cons (insert Zero elem Nil str) Nil&lt;br /&gt;
 	insertAtEveryPos str elem pos = (insertAtEveryPos str elem (pos -. natOne)) ++ (Cons (insert pos elem Nil str) Nil)&lt;br /&gt;
 &lt;br /&gt;
 	insertAtEveryPosForList :: List (List a) -&amp;gt; a -&amp;gt; List (List a)&lt;br /&gt;
 	insertAtEveryPosForList (Cons x Nil) elem = insertAtEveryPos x elem (length x)&lt;br /&gt;
 	insertAtEveryPosForList (Cons x xs) elem = (insertAtEveryPosForList xs elem) ++ (insertAtEveryPos x elem (length x))&lt;br /&gt;
&lt;br /&gt;
==А так же==&lt;br /&gt;
* Дают тип какого-нибудь foldr и просят написать какой-нибудь foldr.&lt;br /&gt;
* Написать определения каких-нибудь тайпклассов.&lt;br /&gt;
* Написать какие-нибудь инстансы.&lt;br /&gt;
* Доказать эквивалетность каких-нибудь двух определений монады.&lt;br /&gt;
* CPS-преобразовать какие-нибудь типы.&lt;br /&gt;
* Написать монадные инстансы для CPS-преобразованных типов.&lt;br /&gt;
&lt;br /&gt;
=Кр4=&lt;/div&gt;</summary>
		<author><name>5.18.174.153</name></author>	</entry>

	</feed>