мета-данные страницы
Загрузка не удалась. Возможно, проблемы с правами доступа?
Различия
Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версияСледующая версияСледующая версия справа и слева | ||
haskell [13/03/2018 14:33] – [6.5 Работа с файлами] Владимир Власов | haskell [30/09/2018 23:05] – [3.8 Дополнительные функции из модуля Data.List] Владимир Власов | ||
---|---|---|---|
Строка 25: | Строка 25: | ||
- [[http:// | - [[http:// | ||
- [[http:// | - [[http:// | ||
- | - [[http://dev.by/blogs/ | + | - [[https://events.dev.by/lenta/ |
- [[http:// | - [[http:// | ||
- [[https:// | - [[https:// | ||
Строка 40: | Строка 40: | ||
**Полезные команды** в ghci: | **Полезные команды** в ghci: | ||
- | :q -- выйти из оболочки; | + | '' |
- | :l <имя программы> | + | '' |
- | :r -- перегрузить текущий модуль; | + | '' |
- | :t <имя функции> | + | '' |
- | :i <имя функции> | + | '' |
Кроме того, надо знать, что выражения в оболочке интерпретатора можно сразу вычислять. | Кроме того, надо знать, что выражения в оболочке интерпретатора можно сразу вычислять. | ||
- | Наберем 2 + 2 и нажмем Enter, или наберем abs (-2) и нажмем Enter, и т.д. | + | Наберем 2 + 2 и нажмем Enter, или наберем |
Новые функции (пользовательские) можно задавать, | Новые функции (пользовательские) можно задавать, | ||
Строка 58: | Строка 58: | ||
> let {f :: Int -> Int; f n = n * 2} | > let {f :: Int -> Int; f n = n * 2} | ||
</ | </ | ||
+ | |||
+ | Отметим, | ||
Многострочные записи делают следующим образом: | Многострочные записи делают следующим образом: | ||
Строка 76: | Строка 78: | ||
</ | </ | ||
- | Для просмотра тех или иных значений функции f можно попробовать набрать f 4, а для просмотра произвольного значения foo набрать show foo. | + | Для просмотра тех или иных значений функции |
Строка 90: | Строка 92: | ||
и мы уже вряд ли сможем посчитать факториал с аргументом более 31. | и мы уже вряд ли сможем посчитать факториал с аргументом более 31. | ||
- | Остальной код задан в виде уравнений, | + | Остальной код задан в виде уравнений, |
- | Возможно использование рекурсии при описании функции. При вызове функций им передается | + | |
<code haskell> | <code haskell> | ||
Строка 136: | Строка 137: | ||
В Haskell возможно описание вычисления функции в | В Haskell возможно описание вычисления функции в | ||
зависимости от условий в более-менее традиционном ключе, для чего | зависимости от условий в более-менее традиционном ключе, для чего | ||
- | присутствуют операторы if и case. Однако, | + | присутствуют операторы |
аналогичных операторов в императивных языках. (Правильнее их называть | аналогичных операторов в императивных языках. (Правильнее их называть | ||
- | выражениями с использованием case- и if-then-else-конструкций) | + | выражениями с использованием |
< | < | ||
Строка 147: | Строка 148: | ||
</ | </ | ||
- | Оператор if предназначен для ветвления вычислительного процесса в | + | Ключевое слово '' |
- | зависимости от условия булевского типа. Части then и else обязательны, | + | зависимости от условия булевского типа. Части |
в отличие от императивного аналога задают не порядок действий, | в отличие от императивного аналога задают не порядок действий, | ||
- | которые возвращают результат для задаваемой функции. Данный оператор | + | которые возвращают результат для задаваемой функции. Данное |
- | частным, | + | частным, |
Иными словами, | Иными словами, | ||
Строка 167: | Строка 168: | ||
</ | </ | ||
- | Рассмотрим более сложные примеры с case-выражениями: | + | Рассмотрим более сложные примеры с '' |
< | < | ||
Строка 182: | Строка 183: | ||
</ | </ | ||
- | Последний пример является комбинацией использования case-выражения с << | + | Последний пример является комбинацией использования |
для предотвращения применения функции для отрицательных аргументов. | для предотвращения применения функции для отрицательных аргументов. | ||
Стоит также упомянуть, | Стоит также упомянуть, | ||
- | рассматривать как упрощенную запись с соответствующими case-выражениями. | + | рассматривать как упрощенную запись с соответствующими |
- | **__Упражнение__.** Задать функцию sign(x) из предыдущего упражнения, | + | **__Упражнение__.** Задать функцию |
- | ==== 2.2 Карринг и лябда-абстракция ==== | + | ==== 2.2 Карринг и лямбда-абстракция ==== |
- | **Карринг.** Отметим, | + | **Карринг.** Отметим, |
Для чего нужен карринг и такие сложности? | Для чего нужен карринг и такие сложности? | ||
- | Рассмотрим выше заданную функцию | + | Рассмотрим выше заданную функцию |
<code haskell> | <code haskell> | ||
Строка 203: | Строка 204: | ||
</ | </ | ||
- | Тогда мы легко можем задать частный случай сложения, | + | Тогда мы легко можем задать частный случай сложения, |
<code haskell> | <code haskell> | ||
Строка 233: | Строка 234: | ||
Если мы подставим в качестве аргумента 4, то увидим разницу значений | Если мы подставим в качестве аргумента 4, то увидим разницу значений | ||
- | функций | + | функций |
- | В следующем, | + | В следующем, |
различными способами (можно запустить функции для проверки с аргументами 4 и 5): | различными способами (можно запустить функции для проверки с аргументами 4 и 5): | ||
Строка 252: | Строка 253: | ||
качестве второго аргумента. Например, | качестве второго аргумента. Например, | ||
готовую функцию, | готовую функцию, | ||
- | в ghci наберите show l1 и show l2. | + | в '' |
<code haskell> | <code haskell> | ||
- | l1 = map abs [-1, 2, -4.2] | + | l1 = map abs [(-1), 2, (-4.2)] |
- | l2 = map (\x -> if x >= 0 then x else negate x) [-1, 2, -4.2] | + | l2 = map (\x -> if x >= 0 then x else negate x) [(-1), 2, (-4.2)] |
</ | </ | ||
Строка 262: | Строка 263: | ||
<code haskell> | <code haskell> | ||
- | l3 = map ((\x -> if x >= 0 then x else negate x)::(Double -> Double) [-1, 2, -4.2] | + | l3 = |
+ | | ||
+ | then x | ||
+ | else negate x)::(Double -> Double)) | ||
+ | | ||
</ | </ | ||
- | |||
==== 2.3 Замыкания (локальные определения)==== | ==== 2.3 Замыкания (локальные определения)==== | ||
Строка 286: | Строка 290: | ||
применении они очень похожи! | применении они очень похожи! | ||
- | < | + | < |
roots' a b c = (x1,x2) where | roots' a b c = (x1,x2) where | ||
d = b^2 - 4*a*c | d = b^2 - 4*a*c | ||
Строка 298: | Строка 302: | ||
При упрощённом подходе мы не отслеживаем случаи, | При упрощённом подходе мы не отслеживаем случаи, | ||
- | < | + | < |
roots' a b c | ((a == 0) && (b == 0)) = error "No roots at all!" | roots' a b c | ((a == 0) && (b == 0)) = error "No roots at all!" | ||
| ((a == 0) && (b /= 0)) = (x,x) -- let x = -c/b in (x, | | ((a == 0) && (b /= 0)) = (x,x) -- let x = -c/b in (x, | ||
Строка 379: | Строка 383: | ||
</ | </ | ||
- | Вот версия более простого и понятного примера: | + | < |
+ | Как показали дальнейшие изыскания, | ||
+ | [[https:// | ||
+ | < | ||
+ | Prelude> :set -XMonomorphismRestriction | ||
+ | Prelude> let x = 2 | ||
+ | Prelude> x + 2.0 | ||
+ | |||
+ | < | ||
+ | * No instance for (Fractional Integer) | ||
+ | arising from the literal `2.0' | ||
+ | ... | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | Вот версия более простого и понятного примера, без странностей ограничения мономорфизма: | ||
<code haskell> | <code haskell> | ||
Строка 390: | Строка 410: | ||
In an equation for `it': it = x + y | In an equation for `it': it = x + y | ||
</ | </ | ||
- | В языках типа Си это соответствовало бы объявлению и инициализации переменных типа | + | В языках типа Си это соответствовало бы объявлению и инициализации переменных типа |
==== 2.6 Использование монады состояния==== | ==== 2.6 Использование монады состояния==== | ||
Пока без комментариев, | Пока без комментариев, | ||
- | < | + | < |
import Control.Monad.State | import Control.Monad.State | ||
- | fact' :: Integer -> State Integer Integer -- тип состояния - Int, тип результата - тоже | + | fact' :: Integer -> State Integer Integer |
+ | -- тип состояния - Integer, тип результата - тоже | ||
fact' 0 = do | fact' 0 = do | ||
acc <- get -- получаем накопленный результат | acc <- get -- получаем накопленный результат | ||
Строка 407: | Строка 428: | ||
fact' (n - 1) -- продолжаем вычисление факториала | fact' (n - 1) -- продолжаем вычисление факториала | ||
- | -- fact :: Int -> Int | + | -- fact :: Integer |
fact n = fst $ runState (fact' n) 1 -- начальное значение состояния = 1 | fact n = fst $ runState (fact' n) 1 -- начальное значение состояния = 1 | ||
</ | </ | ||
Строка 415: | Строка 436: | ||
**__Задания к уроку__** | **__Задания к уроку__** | ||
- | 1. Используя примеры из урока, написать код и исполнить его в ghci, проверить тип полученных функций. | + | 1. Используя примеры из урока, написать код и исполнить его в '' |
- | 2. Сделать тоже самое в отдельном файл и загрузить его в ghci с помощью команды :l. | + | 2. Сделать тоже самое в отдельном файл и загрузить его в '' |
- | 3. Написать код для функций | + | 3. Написать код для функций |
===== Урок 3. Списки как типы ===== | ===== Урок 3. Списки как типы ===== | ||
Строка 433: | Строка 454: | ||
(везде ниже '' | (везде ниже '' | ||
- | * '' | + | * '' |
- | * '' | + | * '' |
- | * '' | + | * '' |
- | * '' | + | * '' |
- | * '' | + | * '' |
* '' | * '' | ||
- | * '' | + | * '' |
==== 3.2 Добавление к списку === | ==== 3.2 Добавление к списку === | ||
Строка 515: | Строка 536: | ||
Все функции, | Все функции, | ||
* '' | * '' | ||
- | * '' | + | * '' |
* '' | * '' | ||
* '' | * '' | ||
Строка 563: | Строка 584: | ||
**Задача 1.** Написать код, генерирующий потенциально бесконечный | **Задача 1.** Написать код, генерирующий потенциально бесконечный | ||
- | список чисел Фиббоначи. Рассмотреть возможности " | + | список чисел Фибоначчи. Рассмотреть возможности " |
Строка 578: | Строка 599: | ||
<code haskell> | <code haskell> | ||
- | import | + | import |
</ | </ | ||
Строка 594: | Строка 615: | ||
* '' | * '' | ||
* '' | * '' | ||
- | * ''< | + | * ''< |
* '' | * '' | ||
* '' | * '' | ||
Строка 801: | Строка 822: | ||
При сопоставлении с образцом будем писать: | При сопоставлении с образцом будем писать: | ||
- | < | + | < |
absPoint' | absPoint' | ||
</ | </ | ||
Строка 807: | Строка 828: | ||
или | или | ||
- | < | + | < |
absPoint'' | absPoint'' | ||
</ | </ | ||
Строка 1509: | Строка 1530: | ||
writeFile " | writeFile " | ||
</ | </ | ||
- | Здесь операция '' | + | Здесь операция '' |
Рассмотрим это же решение, | Рассмотрим это же решение, | ||
Строка 1524: | Строка 1545: | ||
writeFile " | writeFile " | ||
</ | </ | ||
- | Здесь " | + | Здесь " |
- | Работа с " | + | Работа с " |
**Задание к уроку.** Написать программку, | **Задание к уроку.** Написать программку, | ||
Строка 1536: | Строка 1557: | ||
Во-вторых возможен запуск на прямое исполнение командой ''< | Во-вторых возможен запуск на прямое исполнение командой ''< | ||
<code bash># | <code bash># | ||
- | В-третьих, | + | В-третьих, |
==== 6.7 Кратко о монаде IO ==== | ==== 6.7 Кратко о монаде IO ==== | ||
Строка 1544: | Строка 1565: | ||
===== Урок 7. Знакомство с монадами ===== | ===== Урок 7. Знакомство с монадами ===== | ||
- | Понятие монад пришло из чистой математики, | + | Понятие монад пришло из чистой математики, |
Необходимость монад в чистом функциональном программировании возникает из ограничения, | Необходимость монад в чистом функциональном программировании возникает из ограничения, | ||
Строка 1717: | Строка 1738: | ||
</ | </ | ||
- | Здесь как раз видно, что обычные комбинаторы функции '' | + | Здесь как раз видно, что обычные комбинаторы функции '' |
<code haskell> | <code haskell> | ||
f >=> g = \x -> (f x >>= g) | f >=> g = \x -> (f x >>= g) |