Курс Хаскель от джуна до мидла
Курс Хаскель от джуна до мидла

Полная версия

Курс Хаскель от джуна до мидла

Настройки чтения
Размер шрифта
Высота строк
Поля
На страницу:
4 из 4

:browse — показать содержимое модуля

:main — запустить main

:set — установить опции

:unset — сбросить опции

:show bindings — показать определённые имена

:show modules — показать загруженные модули

:show packages — показать пакеты

:def — определить макрос

:undef — удалить макрос

:cd — сменить директорию

:edit — открыть редактор

:etags — сгенерировать tags

:ctags — сгенерировать ctags


Примеры использования :kind:

:k Maybe — * -> *

:k Either — * -> * -> *

:k Int — *


2.13. Создание и использование .ghci файла


Пример ~/.ghci:


:set prompt "λ> "

:set prompt-cont "λ| "

:set +t

:set -Wall

:set -XOverloadedStrings

:set -XFlexibleContexts

:set -XTypeApplications

:def hoogle \x -> return $ ":!hoogle " ++ x

:def docs \x -> return $ ":!hoogle --info " ++ x


Теперь можно писать:

λ> :hoogle map

λ> :docs fmap


2.14. Работа с Cabal (базовый workflow)


cabal init --interactive

cabal build

cabal run

cabal test

cabal repl -- GHCi с зависимостями проекта

cabal install --lib some-package

cabal update

cabal freeze -- зафиксировать версии

cabal outdated


2.15. Stack workflow


stack new project-name

stack build

stack exec project-name-exe

stack test

stack ghci

stack install

stack upgrade


Многие разработчики в 2020-х предпочитают cabal + ghcup, но stack всё ещё популярен благодаря snapshot'ам Stackage.


ГЛАВА 3. РАСШИРЕННЫЙ МАТЕРИАЛ: ТИПЫ И СИНТАКСИС


3.14. Подробно о числовых типах


Int — минимум ±2^29, обычно ±2^63

Int8, Int16, Int32, Int64

Word, Word8 ... Word64 — беззнаковые

Integer — произвольная точность

Float, Double

Rational — точные дроби (Ratio Integer)

Complex Double


Преобразования:

fromIntegral :: (Integral a, Num b) => a -> b

realToFrac :: (Real a, Fractional b) => a -> b

fromInteger :: Num a => Integer -> a

toInteger :: Integral a => a -> Integer


3.15. Подробно о логических операциях и сравнениях


(&&) || not

== /= < > <= >=

compare :: Ord a => a -> a -> Ordering -- LT | EQ | GT


min, max


3.16. Ещё примеры с where и let


-- Вычисление корней квадратного уравнения

quadratic a b c

| disc < 0 = Nothing

| otherwise = Just (x1, x2)

where

disc = b*b - 4*a*c

sqrtDisc = sqrt disc

x1 = (-b + sqrtDisc) / (2*a)

x2 = (-b - sqrtDisc) / (2*a)


-- let в выражениях

let result = let x = 10

y = 20

in x * y + 5

in result


3.17. Большое количество упражнений


1. Напишите функцию isTriangle a b c.

2. Напишите функцию isRightTriangle a b c (проверка теоремы Пифагора).

3. Реализуйте функцию clamp low high value.

4. Напишите функцию, которая возвращает строку "Fizz", "Buzz", "FizzBuzz" или число (классическая задача).

5. Создайте функцию, форматирующую число секунд в "Dd Hh Mm Ss".

6. Напишите функцию, вычисляющую расстояние между двумя точками на плоскости.

7. Реализуйте функцию, определяющую квадрант точки.

8. Напишите функцию, которая по году возвращает век.


ГЛАВА 4. РАСШИРЕННЫЙ ПРАКТИЧЕСКИЙ МАТЕРИАЛ И ПРИМЕРЫ


Ниже приведены дополнительные подробные примеры, разборы типичных ошибок и упражнения повышенной сложности для главы 4.


Примеры кода:


-- Пример 1

example1 :: [Int] -> Int

example1 xs = foldr (+) 0 (map (^2) (filter even xs))


-- Пример 2

example2 :: Maybe Int -> Maybe Int -> Maybe Int

example2 mx my = do

x <- mx

y <- my

return (x + y)


-- Пример 3

example3 :: Either String Int -> Either String Int

example3 e = case e of

Left err -> Left ("Ошибка: " ++ err)

Right n -> Right (n * 2)


-- Пример 4 (рекурсия)

example4 :: [a] -> [a]

example4 [] = []

example4 [x] = [x]

example4 (x:y:xs) = y : x : example4 xs


-- Пример 5 (высшие функции)

example5 :: (a -> Bool) -> [a] -> [a]

example5 p = foldr (\x acc -> if p x then x:acc else acc) []


Типичные ошибки новичков в этой теме:

• Забывают, что паттерн-матчинг идёт сверху вниз.

• Путают foldl и foldr.

• Пытаются использовать изменяемые переменные.

• Игнорируют предупреждения компилятора.

• Пишут слишком общие типы там, где нужны конкретные.

• Злоупотребляют partial-функциями (head, tail, !!, fromJust).


Советы по стилю:

• Давайте функциям говорящие имена.

• Добавляйте type signatures почти везде.

• Разбивайте сложные функции на маленькие.

• Используйте where для вспомогательных определений.

• Предпочитайте тотальные функции.


Упражнения повышенной сложности:


1. Реализуйте функцию, которая принимает список и возвращает список всех его подсписков (powersets).

2. Напишите функцию groupBy с кастомным компаратором равенства.

3. Реализуйте собственную версию mapAccumL / mapAccumR.

4. Создайте функцию, которая безопасно достаёт элемент по индексу и возвращает Maybe.

5. Напишите функцию, которая разбивает список на куски фиксированного размера (chunksOf).

6. Реализуйте zipWith3, zipWith4 через рекурсию или fold.

7. Напишите функцию, которая находит все позиции вхождения элемента в список.

8. Создайте функцию unique, сохраняющую порядок первого вхождения.

9. Реализуйте intersperse и intercalate самостоятельно.

10. Напишите функцию, которая проверяет, является ли один список подсписком другого.


Дополнительные рассуждения:


При работе с этой темой важно постоянно спрашивать себя:

- Можно ли сделать эту функцию тотальной?

- Можно ли выразить её через уже существующие высшие функции?

- Насколько легко её тестировать?

- Хорошо ли читается point-free версия или лучше оставить явные аргументы?


Чем больше вы практикуетесь, тем быстрее начинаете "видеть" решения в терминах map / filter / fold / unfold / traverse.


ГЛАВА 5. РАСШИРЕННЫЙ ПРАКТИЧЕСКИЙ МАТЕРИАЛ И ПРИМЕРЫ


Ниже приведены дополнительные подробные примеры, разборы типичных ошибок и упражнения повышенной сложности для главы 5.


Примеры кода:


-- Пример 1

example1 :: [Int] -> Int

example1 xs = foldr (+) 0 (map (^2) (filter even xs))


-- Пример 2

example2 :: Maybe Int -> Maybe Int -> Maybe Int

example2 mx my = do

x <- mx

y <- my

return (x + y)


-- Пример 3

example3 :: Either String Int -> Either String Int

example3 e = case e of

Left err -> Left ("Ошибка: " ++ err)

Right n -> Right (n * 2)


-- Пример 4 (рекурсия)

example4 :: [a] -> [a]

example4 [] = []

example4 [x] = [x]

example4 (x:y:xs) = y : x : example4 xs


-- Пример 5 (высшие функции)

example5 :: (a -> Bool) -> [a] -> [a]

example5 p = foldr (\x acc -> if p x then x:acc else acc) []


Типичные ошибки новичков в этой теме:

• Забывают, что паттерн-матчинг идёт сверху вниз.

• Путают foldl и foldr.

• Пытаются использовать изменяемые переменные.

• Игнорируют предупреждения компилятора.

• Пишут слишком общие типы там, где нужны конкретные.

• Злоупотребляют partial-функциями (head, tail, !!, fromJust).


Советы по стилю:

• Давайте функциям говорящие имена.

• Добавляйте type signatures почти везде.

• Разбивайте сложные функции на маленькие.

• Используйте where для вспомогательных определений.

• Предпочитайте тотальные функции.


Упражнения повышенной сложности:


1. Реализуйте функцию, которая принимает список и возвращает список всех его подсписков (powersets).

2. Напишите функцию groupBy с кастомным компаратором равенства.

3. Реализуйте собственную версию mapAccumL / mapAccumR.

4. Создайте функцию, которая безопасно достаёт элемент по индексу и возвращает Maybe.

5. Напишите функцию, которая разбивает список на куски фиксированного размера (chunksOf).

6. Реализуйте zipWith3, zipWith4 через рекурсию или fold.

7. Напишите функцию, которая находит все позиции вхождения элемента в список.

8. Создайте функцию unique, сохраняющую порядок первого вхождения.

9. Реализуйте intersperse и intercalate самостоятельно.

10. Напишите функцию, которая проверяет, является ли один список подсписком другого.


Дополнительные рассуждения:


При работе с этой темой важно постоянно спрашивать себя:

- Можно ли сделать эту функцию тотальной?

- Можно ли выразить её через уже существующие высшие функции?

- Насколько легко её тестировать?

- Хорошо ли читается point-free версия или лучше оставить явные аргументы?


Чем больше вы практикуетесь, тем быстрее начинаете "видеть" решения в терминах map / filter / fold / unfold / traverse.


ГЛАВА 6. РАСШИРЕННЫЙ ПРАКТИЧЕСКИЙ МАТЕРИАЛ И ПРИМЕРЫ


Ниже приведены дополнительные подробные примеры, разборы типичных ошибок и упражнения повышенной сложности для главы 6.


Примеры кода:


-- Пример 1

example1 :: [Int] -> Int

example1 xs = foldr (+) 0 (map (^2) (filter even xs))


-- Пример 2

example2 :: Maybe Int -> Maybe Int -> Maybe Int

example2 mx my = do

x <- mx

y <- my

return (x + y)

Конец ознакомительного фрагмента.

Текст предоставлен ООО «Литрес».

Прочитайте эту книгу целиком, купив полную легальную версию на Литрес.

Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.

Конец ознакомительного фрагмента
Купить и скачать всю книгу
На страницу:
4 из 4