Transcript fp13
Зачет
>= 90 баллов
Можете уже в следующий раз приходить с зачеткой
>= 70 баллов
Пришлите, пожалуйста, 3 темы не позже 10:00 10.12
1
Задача на листке про toStr
toStr’ Empty s = 'e':s
toStr’ (Node v l r) = let
s1 = toStr’ r s
s2 = toStr’ l s1
in 'n':v:s2
Задача на листке: записать эти правила, не используя явно
строки s, s1, s2, c помощью операций над функциями
toStr’ Empty = ('e':)
toStr’ (Node v l r) =
('n':) . (v:) . toStr’ l . toStr’ r
2
Еще про >>=
3
return1
Хотим писать цепочки:
Philip Wadler
ff = findpos (>3) >>>= \x->
findpos (>x) >>>= \y ->
return1 (x+y)
Тип:
return1 (x+y)
список -> (значение, список)
return1
значение -> список -> (значение, список)
Итого
return1 val xs = (val, xs)
4
Символьные
вычисления
5
На чем мы остановились
data Expr = Num Integer | Var String | Add Expr Expr | Mult Expr Expr
eval
eval
eval
eval
(Num i) _ = i
(Var name) env = getValue name env
(Add x y) env = eval x n + eval y n
(Mult x y) env = eval x n * eval y n
getValue name env = head [v | (n, v) <- env, n == name]
6
Let
Хотим добавить в Expr let
конструкции
Например,
(let x = 10 in x*y) + 1
Add ( Let "x" (Num 10)
(Mult (Var "x") (Var "y")))
(Num 1)
data Expr = Num Integer |
Var String | Add Expr Expr |
Mult Expr Expr |
Let String Expr Expr
Вариант 1
eval (Let name (Num val)
in_expr) env =
eval in_expr ((name, val):env)
Может быть и выражение
eval (Let name expr in_expr) env =
let
val = eval expr env
in eval in_expr ((name, val):env)
7
Когда вычислять? (Если мы хотим
быть ленивыми)
Когда вычислять let выражение?
1.
При вычислении let
Недостаток: Получается не лениво
2.
Добавлять в env не вычисленное значение
Недостаток: Будем вычислять значение несколько раз
Но с этим мы бороться не будем, условно будет тут
считать, что это нормально
Еще проблема
Что будет, если let выражение содержит переменные?
8
Связывание
let
x=5
in let
y = x*x
in let x = 10
in y+1
Что должно быть?
10*10 + 1
5*5+1
Чем лучше 5*5?
Иначе получится, что y в
разных местах имеет разные
значения. См. referential
transparency
Мы проходили для этого
специальное название:
статическое связывание
9
Как это реализовать
Как это реализовать?
Запоминать в env:
выражение + контекст
контекст – env, в котором вычислять выражение
Фактически это то, что мы называли замыкание
Техническая проблема: получится, что env будет содержать
тройки:
(имя, выражение, env-для-этого-выражения)
Но список не может содержать сам себя
Выход: ввести вспомогательный тип, который создаст
‘прослойку’ между env и его элементом который тоже env
Например, описать тип
data Closure = Closure Expr [(String, Closure)]
И это будет доп.задача, в субботу
10
LetFunc – напоминание постановки
задачи
data Expr = Num Integer | Var String | Add Expr Expr | Mult Expr Expr |
Let String Integer Expr |
LetFunc String String Expr Expr |
Call String Expr
Пример вызова:
eval (LetFunc "F" "X"
(Mult (Var "X") (Var "X")) (Add (Num 1)
(Call "F" (Num 5))))
[] []
11
LetFunc - решение
eval (LetFunc name param body expr) env funcEnv =
eval expr env ((name, (param, body)):funcEnv)
(param, body) – что-то вроде лямбда выражения
eval (Call name expr) env funcEnv = let
(param, body) = getFuncValue name funcEnv
paramValue = eval expr env funcEnv
in eval body ((param, paramValue):env) funcEnv
Недостаток:
тоже так не получается статическое связывание
12
Лямбда-исчисление
13
Числа Черча - напоминание
\f
\f
\f
\f
\ f x -> …
x
x
x
x
->
->
->
->
x
fx
f (f x)
f (f (f x))
0
1
2
3
14
toInt
Число Черча – машинка, которая повторяет данное действие
данное число раз (начиная с данного значения)
toInt chNum = chNum
(+1)
0
toInt (\f x -> f (f (f x)))
(\f x -> f (f (f x))) (+1) 0
(+1) ((+1) ((+1) 0))
3
15
add, inc
add chNum1 chNum2
add chNum1 chNum2 =
\f x ->
let
x1 = chNum1 f x
x2 = chNum2 f x1
in x2
inc
inc chNum = \f x -> let
x1 = chNum f x
in f x1
или короче
inc chNum = \f x -> f (chNum f x)
или короче
add chNum1 chNum2 = \ f x ->
chNum2 f (chNum1 f x)
16
dec – подсказка, как это можно
сделать с парами
Идея 1: используем пары
Взять (0,0)
Повторить n раз:
(a, b) -> (inc a, a)
Получится: (n, предыдущее
перед n)
Пример для 3:
(0,0)
(1,0)
(2,1)
(3,2)
Под 0, n, a, b имеются в виду
соответствующие числа Черча
"Повторить n раз" – это как раз
то, что числа Черча умеют делать
17
dec – подсказка, как моделировать пары
лямбда выражениями реализовать
Идея 2: пары можно моделировать функциями
Примерно так же, как мы функциями моделируем числа
«Пара Черча» для a и b - \f -> f a b
Например, пара Черча для 2 и 3:
\f -> f 2 3
Создать пару:
pair a b = \f -> f a b
p = pair 2 3
функция, которой мы даем на вход фунцкию от двух
переменных, и она ее вызывает
p (+) 5
p (*) 6
Остается понять, что для пар Черча соответствует fst и snd
И это будет еще одна доп.задача, в субботу
18
Редукции
Что такое вычисление для чистого лямбда исчисления?
Что-то вроде упрощения выражения
Упрощаем выражение по данным правилам пока что-то можно
упростить
Правило по сути одно: бета-редукция
Есть еще альфа-конверсия, гамма-редукция и эта-конверсия,
но они менее важные
Например: альфа-конверсия:
связанные переменные можно переименовать.
Например, \x f x – это то же, что \y f y
19
Бета-редукция
(\ x (mult x x)) 5
mult 5 5
Бета-редукция
(\ x expr1 ) expr2
expr1, в котором вместо
всех вхождений x
подставленно выражение
expr2
Еще примеры:
(\ x x) y
y
(\ x (x x)) y
yy
(Формулировка
специально не совсем
корректная, см. д.з.)
20
Более формально: что такое вычисление по Черчу.
Существование нормальной формы
Редекс – подвыражение, к
которому можно применить
бета- редукцию
Нормальная форма –
выражение, в котором нет
редексов
Вычисление по Черчу – это
применение редукций, пока
не получим нормальную
форму
Типичные вопросы в
математике:
существование
единственность
Всегда ли существует
нормальная форма?
Нет. Например:
(\x x x) (\x x x)
(\x x x) (\x x x)
… и так до бесконечности
21
Единственность нормальной формы.
Конфлюентность
Верно ли, что если нормальная форма существует,
то она единственна?
Определение: Выражение A редуцируемо к B, если
B можно получить из A применением некоторого
количества редукций (может быть, нулевого
количества)
Определение: Редукции обладают
свойстом конфлюентности,
если для любого выражения A:
Если A редуцируемо к выражению B
и в то же время A редуцируемо к
выражению С
то существует такое выражение D, что
B редуцируемо к В и С редуцируемо к D.
То есть, в
частности,
любое
выражение
редуцируемо к
самому себе
confluent сливающийся
22
Конфлюентность - продолжение
Теорема (Черч, Россер) (не очень простая): чистое лямбдаисчисление обладает свойством конфлюентности
Теорема (очень простая): Если у лямбда выражения существует
нормальная форма, то она единственна
Будет в д.з.
23
Порядок вычислений
Значит, порядок редукций вообще не важен?
Все-таки важен
Может получиться, что при одном порядке вычислений мы
получаем нормальную форму, а при другом – не получаем
(зацикливаемся)
24
Нормальный и аппликативный
порядок
Обычно рассматривают такие порядки редукций:
Аппликативный
Каждый раз берем тот редекс, который расположен глубже
всего (в нем нет других редексов)
Нормальный
Каждый раз берем самый внешний редекс, который не
содержится ни в каком другом редексе
Замечательное свойство:
Если есть нормальная форма, то нормальный порядок
обязательно к ней придет
Д.з.: Привести пример выражения, для которого при нормальном
и аппликативном порядке получаются разные результаты
25
Оператор неподвижной точки
На занятии мы говорили про то, что такое оператор неподвижной
точки, но, пожалуй, лучше мы это в следующий раз еще
повторим
26