1 / 33

Контрольная работа

Контрольная работа. 20 октября примерно на час Примерно 10 простых задач Накапливающие параметры Работа со списками Списки списков Пары data (типа торты , фильмы ) map foldr Деревья List comprehension. Как будет проходить

sara-craig
Download Presentation

Контрольная работа

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Контрольная работа • 20 октября • примерно на час • Примерно 10 простых задач • Накапливающие параметры • Работа со списками • Списки списков • Пары • data (типа торты, фильмы) • map • foldr • Деревья • List comprehension • Как будет проходить • Можно пользоваться любыми материалами(интернетом, компьютерами, распечатками, книгами и т.д.) • Нельзя пользоваться чьей-либо помощью в любой форме • Сдавать можно будет на листке, на любом носителе или послать по почте • Могут быть мелкие синтаксические ошибки

  2. Д.з.

  3. swapSymbols swapSymbols xs = map (\x -> if x == '?' then '!' else if x == '!' then '?' else x) xs swapSymbols xs = map (\x -> case x of '?' -> '!' '!' -> '?' x -> x) xs swapSymbols xs = map swap xs where swap '?' '!' swap '!' '?' swap x x

  4. Задача на листочке f n  [1,-1,1,-1,1,…] (n раз) f n = map (\i -> что-то) [1..n] • что-то – то, что надо сгенерировать для i-того элемента 1  1 2  -1 3  1 4  -1 5  1 … map (\i -> if i `mod` 2 == 1 then 1 else -1) [1..n] • Еще вариант: map (\i -> (-1) ^ i)) [0..n-1] или map (\i -> (-1) ^ mod i 2)) [0..n-1]

  5. Задача на листочке – без map • Вариант 1 f n = f’ 1 n f’ _ 0 = [] f’ x n = x : f’ (-x) (n-1) • Вариант 2 f 0 = [] f 1 = [1] f n = 1:-1:f (n-2) • Типичное замечание: • ++ [x] • Неэффективно :(

  6. multTable multTable 3  [[1,2,3], [2,4,6], [3,6,9]] map (\i-> что-то) [1..n] что-то = сгенерировать i-ю строку i-я строка = [i, 2*i, 3*i, 4*i, … n*i] map (\j->i*j) [1..n] multTable n = map (\i -> map (\j -> i*j ) [1..n]) ) [1..n] • Примерно как for (i = 1; i<=n; i++) { for (j = 1; j<=n; j++) { cout << i*j; } } 1 строка 2строка 3строка

  7. repeatFunc repeatFunc f n = f.f.f … .f - n раз • полезно 'забыть' про смысл оператора (.) repeatFunc f n = f . repeatFunc f (n-1) • Нерекурсивный случай repeatFunc f 1 = f repeatFunc f 0 = ? \x -> x • id – тождественное отображение id x = x • Все вместе: repeatFunc f 0 = id repeatFunc f n = f . repeatFunc f (n-1)

  8. countOdd • countOddxs = foldr (\i res -> if mod i 2 == 1 then res+1 else res) 0 xs Еще варианты: • Выносим res из if countOddxs = foldr (\i res -> res + if mod i 2 == 1 then 1 else 0) 0 xs • Вообще без if countOddxs = foldr (\i res -> res + mod i 2) 0 xs • Короче с каррингом countOdd = foldr (\i res -> res + mod i 2) 0

  9. countOdd1 • countOdd1 xs = length ( filter (\i -> mod i 2 == 1) xs) • countOdd1 xs = length ( filter odd xs ) • odd – стандартная функция • countOdd1 xs = sum (map (`mod` 2) xs) Еще варианты (карринг, комбинаторное программирование): • countOdd1 = length . filter odd • countOdd1 = sum . map (`mod` 2)

  10. myFoldl foldl (+)0 [1,2,3] = (((0+ 1) + 2) + 3) • Свести к задаче для [2,3] (((0 + 1) + 2) + 3) e1 = 0 + 1 ((1 + 2) + 3) foldl (+) 1 [2,3] • Т.е.выразили foldl через foldl от хвоста списка foldl f e (x:xs) = let e1 = e `f` x in foldl f e1 xs • или, короче, foldl f e (x:xs) = foldl f (e `f` x) xs foldl f e [] = e Замечания: • Аргументы f в другом порядке, чем в foldr • Что можно сказать про foldl? • Хвостовая рекурсия • e – накапливающий параметр

  11. Разное

  12. fromIntegral x = sqrt (mod 100 7) • Ошибка – тип Integer и Double x = sqrt (fromIntegral (mod 100 7)) • fromIntegral – преобразует целое в вещественное

  13. Самая выразительная функция? • map • filter • foldr и foldl • Все можно выразить через… • foldr!

  14. Как еще можно понимать foldr

  15. Как еще можно понимать foldr Способ 3 – заменяем в дереве внутреннего представления • Заменяем [] на e • Заменяем : на f • Вычисляем то, что получится

  16. Статичесткое/динамическое связывание

  17. Что тут получится? a = 5-- Определяем a res = let f x = x * a in let a = 7 -- Переопределяем a in f 2 Что получится? • 2*5 = 10 • 2*7 = 14 • 2*5 = 10 • значение a запоминается при определении функции • статическое связывание • 2*7 = 14 • значение a берется при вызове функции • динамическое связывание • Haskell – статическое связывание • ср. referential transparency • f 2всегда должен возвращать одно и то же

  18. Замыкание (closure)

  19. Замыкание • Снова checkDifferent из д.з. 1 checkDifferent (x:xs) = let f t = t == x in if any f xs then False else checkDifferent xs • f – не совсем обычная функция • Мы не можем определить ее внеlet. Почему? • Потому что она содержит переменную x, не локальную в f, но локальную в внешней функции • Другими словами: f содержит переменную,глобальную для f, но локальную для checkDifferent • Это называется замыкание(closure)

  20. Почему это важно? Воображаемый диалог: • Программист A: любитель языка С • Программист B: любитель Haskell (или C# и т.д.) • B: Мы можем определять функции, у которых параметры – другие функции! Например, any. A: Ну и что, я тоже могу написать что-то типа:bool any(int arr[], bool (*f)(int)){ …} • Как убедить, что Хаскел лучше? Задача: написать функцию checkDigit: «Проверить, есть ли в списке / массиве число, оканчивающиеся на d?» Используя any

  21. Почему это важно - продолжение • B: checkDigit d xs = let f x = mod x 10 == d in any f xs • A: bool any(int a[], bool (*f)) { … как-то написал … } … • Но непонятно, что передать в any! boolcheckDigit(int a[], int d) { ??? Как определить f ? ??? Похоже, никак any(a, f); } • Мораль: Без замыканий использовать функции высшего порядка не очень удобно

  22. Замечания • Разные определения: • Замыкание – это функция, в которой есть нелокальные переменные • Структура, где все это хранится • В С++ это capture list any_of(v.begin(), v.end(), [d] (int i) { return i % 10 == d; });

  23. List comprehension

  24. List comprehension(генераторы списков?) • примерно как в математике описываются множества S = { x: x R, x > 5 } Примеры: • Удобная запись для map [sin x | x <- [1..n]]  [sin 1, sin 2, … , sin n] • Удобная запись для filter [x | x <- xs, x > 0] • Отобрать положительные числа • Можно сразу и map и filter [sin x | x <- xs, x > 0] • Отобрать положительные числаи сгенерировать список из их синусов

  25. List comprehension – еще возможности • Декартово произведение [x*y | x<-[1..n], y<-[1..n]] • Список всех попарных произведений • Это уже больше, чем удобная запись для map и filter! Еще пример: [(x,y) | x<-[1..n], y<-[1..n], x^2+y^2 < n^2] • Четверть круга • let переменная = выражение [(x,y) | x<-[1..n], let xx = x*x, y<-[1..n], xx+y^2 < n^2]

  26. Что можно писать в list comprehension? [ выражение | конструкция1, конструкция2, …] • Конструкции: • генератор (generator)выражение <-список x <- [1..n] • охраняющее выражение (guard)логическое выражение x*x+y*y <= 100 • let конструкцияlet выражение1= выражение2 let x2 = x*x

  27. C# (для следующей задачи на ‘обычном’ языке

  28. Аналоги map и filter • Where – аналог filter • Select – аналог map int [] a = { 1, 2, 3, 4, 5 }; double [] b = a.Select(x => Math.Sin(x)).ToArray(); // Теперь в массиве b синусы всех чисел из массива a double [] c = b.Where(x => x > 0).ToArray(); // Теперь в массиве с все положительные числа из массива b // А можно сразу применить и Select и Where double [] c1 = a.Select(x => Math.Sin(x)). Where(x => x>0).ToArray(); • Или можно использовать LINQ query expressions (выражения запросов)

  29. Про некоторые доп.задачи

  30. nseq nseq n = nseqFrom 1 n nseqFrom k n = if k*2 >= n then 1 else nseqFrom (k+1) (n-k) + nseqFrom (k+1) n • Тест map [1..100] nseq Как сосчитать быстрее? • Динамическое программирование! • nseqFrom k n – количество последовательностей, в которых все числа >= n • nseqFrom 2 16 / \ Содержит 2Не содержит 2 23 4 73 4 9 23 5 6 3 5 8 2 3 11 3 6 7 2 4 10 3 13 2 5 9 4 5 7 … … nseqFrom3 14+nseqFrom3 16

  31. Integral static double Integral(Func<double, double> f, double a, double b) { double sum = 0; var h = (b - a)/100; for (var x = a + h/2; x < b; x += h) sum += f(x)*h; return sum; } • Пример вызова: var result = Integral(x => x*x, 0, 2); • Замечание: • sum += (f(x)+f(x+h))/2 • Два вызова f в цикле – неэффективно… • В функциях высшего порядка важно вызыватьне вызывать параметры лишний раз!

  32. Д.з.

  33. Иллюстрация к задаче 4 • 5 коп • 3 коп • 2 коп

More Related