1 / 26

Refrential transparency

Refrential transparency. Что такое ‘ побочный эффект ’ ? Прозрачность по ссылкам ( referential transparency) … f 5 + … f 5 … Вызовы с одинаковыми параметрами всегда дают одинаковые значения Можно заменить на один вызов x = f 5 … x + … x …. Не очень понятно: А как же случайные числа??

larue
Télécharger la présentation

Refrential transparency

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. Refrential transparency • Что такое ‘побочный эффект’? • Прозрачность по ссылкам (referential transparency) … f 5 + … f 5 … • Вызовы с одинаковыми параметрами всегда дают одинаковые значения • Можно заменить на один вызовx = f 5… x + … x … Не очень понятно: • А как же случайные числа?? • А как же ввод/вывод??

  2. Д.з.

  3. ((2^2)^2)…^2 f n = (((2^2)^2)…^2)^2 f (n-1) f 0 = 2 f n = f (n-1)^ 2 Еще одно решение: f 0 = 2 f n = f (n-1)* f (n-1) f 10  f 9 – 2 раза f 8 – 4 раза f 7 – 8 раз … f 0 – 1024 раза O(2^n) :(

  4. 0+1/(1+1/(2+1/3+…)) b n = 0+1/(1+1/(2+1/3+…)) • При трудностях помогает доп.параметр • b’ k n = k+1/(k+1+1/(...+1/n))) b n = b' 0 n b' k n = if (k == n) then n else k + 1 / b' (k+1) n

  5. sumsqr (1+2+...+n)^2 - (1^2 + 2^2 +... + n^2) Накапливающие параметры s s2 0 0 1 1^2 1+2 1^2 + 2^2 1+2+3 1^2 + 2^2 + 3^2 … sumsqr n = sumsqr' n 0 0 sumsqr' 0 s s2 = s^2 - s2 sumsqr' n s s2 = sumsqr' (n-1) (s+n) (s2+n^2) s  s+n s2  s2+n^2 5

  6. sumfact 1!+2!+3!+…+n! Желательно O(n) i p s 1 1 0 2 11 3 1*2 1+1*2 4 1*2*3 1+1*2+1*2*3 5 1*2*3*4 1+1*2+1*2*3+1*2*3*4 sumfact n = sumfact' n 1 1 0 sumfact' 0 i p s = s sumfact' n i p s = sumfact' (n-1) (i+1) (p*i) (s+p*i) i  i+1 p  p*i s  s+p*i 6

  7. Безымянная переменная (wildcard) sumfact' 0 i ps = s Лучше так: sumfact' 0 _ _ s = s _ - безымянная переменная (wildcard) Только слева от = с с 7

  8. let sumfact' n i p s = sumfact' (n-1) (i+1) (p*i) (s+p*i) Еще одна проблема(небольшаяв данном случае) p*i – два раза DRY (Don’t Repeat Yourself) sumfact' n i p s = let p’ = p*i in sumfact' (n-1) (i+1) p’ (s+p’) с с 8

  9. let в общем случаеДвумерныйсинтаксис let правило1 правило2 … in выражение • Могут быть и правила с параметрами • М.б. частью выражения f n = 1 + let i = 55 j = n*n + 5* n + 8 g k = k * j in g n * 2 Где кончается правило и начинается следующее? • Двумерный синтаксис (off-side rule) • Запоминаем позицию первой лексемы после let (iвпримере) • Правее продолжение правила • На том же уровне  новое правило • Левее  конец конструкции 9

  10. Явное задание синтаксиса let правило1 правило2 … in выражение • Можно использовать { ; }, тогда отступы не имеют значение let{правило1; правило2; правило3} in выражение 10

  11. where sumfact' n i p s = sumfact' (n-1) (i+1) p’ (s+p’) where p’ = p*i левая часть = правая частьwhere вспомогательные определения • Разница: • let можно писать где угодно • where – часть правила • Тоже двумерный синтаксис

  12. Списки

  13. Списки • Основной тип данных • (и почти во всех функциональных языках) • Примеры: [1, 2, 3] [3.5, 2.123, 98.14] [True, False] • Элементы д.б. одного типа! [1, True, 2] -- Ошибка! Потому что Хаскел статически типизированный язык (и тут мы обсуждали, что это значит).

  14. Как создавать списки Оператор : • Оператор : • Приписать элемент в начало 1 : [2,3]  [1,2,3] • Пример: f 0 = [] f n = n : f (n-1) • Список чисел от n до 1 • Кстати:[a..b] – числа от a до b с шагом 1 • На самом деле, [1,2,3] – это просто сокращение! • [1, 2, 3] – сокращение для 1:2:3:[] • Так и хранится: : / \ 1 : / \ 2 : / \ 3 []

  15. Как обрабатывать списки – способ 1 • head – первый элемент списка • tail – все,кроме первого элемента («хвост») head [1,2,3]  1 tail [1,2,3]  [2,3] • Пример: сумма элементов списка sum [] = 0 sum xs = head xs + sum(tail xs) Замечания: • Типичные имена для списков в Haskel: xs, ysи т.д. • sum – на самом деле, есть такая стандартная функция

  16. ШаблоныКак обрабатывать списки – способ 2 sum [] = 0 sum (x:xs) = x + sum xs • Слева от = м.б. выражение с переменными – шаблон (pattern) • Шаблоны м.б. довольно сложным • Примеры: f [x] f [x, y, z] f [1, y, 2] f (x:y:xs) f (x:1:xs) Замечания: • sum (x:xs) – скобки нужны! • Еще раз, правило линейности: • f [x, y, x] -- ошибка!

  17. Еще пример • product – произведение чисел списка (стандартная функция) product [] = 1 product (x:xs) = x * product xs • Снова факториал fact n = product [1..n] • Это стиль Haskell! • Fritz RuehThe Evolution of a Haskell Programmerhttp://www.willamette.edu/~fruehr/haskell/evolution.html

  18. ++ • Еще одна стандартная функция • Конкатенация [1,2] ++ [3,4]  [1,2,3,4] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) • Кстати: как приписывать в конец списка • xs : x • Нет!: приписывает только в начало! • xs ++x • Нет!++ работает только со списками! • xs ++ [x] • OK • Но O(n) – медленно!

  19. Функции высшего порядка

  20. Пример: map Начальник приказывает: • Взять синус от всех элементов списка sinAll [] = [] sinAll (x:xs) = sin x : sinAllxs • Взять косинус от всех элементов списка cosAll [] = [] cosAll (x:xs) = cos x : cosAllxs • Возвести все элементы списка в квадрат • DRY :( Надо что-то делать! • map map f [] = [] map f (x:xs) = f x : map f xs • Примеры вызова map sin [1,2,3]  [sin 1, sin 2, sin 3] map sqr [1,2,3]  [1,4,9] • Функция высшего порядка!

  21. Лямбда-выражения • Почему в обычных языках (Паскаль, C) этим мало пользуются? • Еще задача: Каждое число в списке умножить на 10 и прибавить 5. f x = 10 * x + 5 map f xs • Надо описывать вспомогательные функции – лень  • Надо придумывать имена – тоже лень  • Лямбда-выражение – функция без имени • \i -> 10*i + 5 map (\i -> 10*i+5) xs • Синтаксис: \ параметр1 параметр2 ->выражение • \ - то, что осталось от λ • Ограничения: • М.б. только одно правило (но case) • Естественно, не м.б. рекурсивно

  22. Разное

  23. trace, show import Debug.Trace … trace строка значение … • Возвращает значение • Печатает строку • Пример: fact 0 = trace "!!!" 1 • show • show 66  "66" • Не требует import, есть почти для всех обьектов • show [1,2,3]  "[1,2,3]" • Примеры trace + show:abs x = if x > 0 then x else trace (show x) (-x)fact i = trace (show i) i *fact (i-1)

  24. Функции высшего порядка в C#Как описыватьпараметры-функции • Как описывать параметры – функции • Как задавать значения для параметров-функций • Как описывать: Func<int, int> f • Func<тип1, тип2, … ,тип_результата> Func<int, double, bool> • Это сокращение для delegate • Специальные случаи: • Predicate<int> pred • функция с одним параметром и логическим значением • Action<int> act Action<int, double> act1 • Функция возвращает void

  25. Как задавать значения для параметров-функций • Что можно передавать в функцию с параметром-функцией? • Имя статического метода • Expression lambdaпараметр => выражение или (параметр, параметр, …) => выражение i => i*i (i, j) => i + j • Можно указывать типы (но обычно не нужно) (int i, int j) => i + j • Statement lambdaпараметр => блок или (параметр1, параметр, …) =>блок n => { int p = 0; for(int i=1;i<=n;i++) p*=i; return p; } • Есть еще возможности (delegate, не статические методы…)

  26. Пример static void PrintTable( Func<int, int> f, int n) { for (int i = 0; i <= n; i++) { Console.WriteLine("{0} {1}", i, f(i)); } } static int Cube(int i) { return i * i * i; } // Примеры вызова: PrintTable(Cube, 10); Func<int, int> sqr = i => i * i; PrintTable(sqr, 10); PrintTable(i => i*i, 10);

More Related