Unknown - haskell-notes

Здесь есть возможность читать онлайн «Unknown - haskell-notes» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Старинная литература, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

haskell-notes: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «haskell-notes»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

haskell-notes — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «haskell-notes», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

eval ( Adda b)

=liftA2 ( +) (eval a) (eval b)

eval ( Mula b)

=liftA2 ( *) (eval a) (eval b)

eval ( Varname) = Reader $\env ->value env name

Определение сильно изменилось, оно стало не таким наглядным. Теперь значение eval стало специаль-

ным, поэтому при рекурсивном вызове функции eval нам приходится поднимать в мир специальных функций

обычные функции вычитания, сложения и умножения. Мы можем записать это выражение

немного по другому:

eval :: Exp -> Reader Env Int

eval ( Litn)

=pure n

eval ( Negn)

=negateA $eval n

eval ( Adda b)

=eval a ‘addA‘ eval b

eval ( Mula b)

=eval a ‘mulA‘ eval b

eval ( Varname) = Reader $\env ->value env name

addA

=liftA2 ( +)

mulA

=liftA2 ( *)

negateA

=liftA negate

Тип Map

Для того чтобы закончить определение функции eval нам нужно определить тип Envи функцию value.

Для этого мы воспользуемся типом Map, он предназначен для хранения значений по ключу.

Этот тип живёт в стандартном модуле Data.Map. Посмотрим на его описание:

data Mapk a = ..

Первый параметр типа k это ключ, а второй это значение. Мы можем создать значение типа Mapиз списка

пар ключ значение с помощью функции fromList.

Посмотрим на основные функции:

-- Создаём значения типа Map

-- создаём

empty :: Mapk a

-- пустой Map

fromList :: Ordk =>[(k, a)] -> Mapk a

-- по списку (ключ, значение)

-- Узнаём значение по ключу

( !)

:: Ordk => Mapk a ->k ->a

Отложенное вычисление выражений | 111

lookup

:: Ordk =>k -> Mapk a -> Maybea

-- Добавляем элементы

insert :: Ordk =>k ->a -> Mapk a -> Mapk a

-- Удаляем элементы

delete :: Ordk =>k -> Mapk a -> Mapk a

Обратите внимание на ограничение Ordk в этих функциях, ключ должен быть экземпляром класса Ord.

Посмотрим как эти функции работают:

*Exp> :m +Data.Map

*Exp Data.Map> :m -Exp

Data.Map> letv =fromList [(1, ”Hello”), (2, ”Bye”)]

Data.Map>v !1

”Hello”

Data.Map>v !3

”*** Exception: Map.find: element not in the map

Data.Map> lookup 3 v

Nothing

Data.Map> let v1 = insert 3 ” Yo” v

Data.Map> v1 ! 3

Yo

Функция lookup является стабильным аналогом функции !. В том смысле, что она определена с помощью

Maybe. Она не приведёт к падению программы, если для данного ключа не найдётся значение.

Теперь мы можем определить функцию value:

import qualified Data.Map asM( Map, lookup, fromList)

...

type Env = M.Map String Int

value :: Env -> String -> Int

value env name =maybe errorMsg $ M.lookup env name

whereerrorMsg = error $”value is undefined for ” ++name

Обычно функции из модуля Data.Mapвключаются с директивой qualified, поскольку имена многих

функций из этого модуля совпадают с именами из модуля Prelude. Теперь все определения из модуля

Data.Mapпишутся с приставкой M..

Создадим вспомогательную функцию, которая упростит вычисление выражений:

runExp :: Exp ->[( String, Int)] -> Int

runExp a env =runReader (eval a) $ M.fromList env

Сохраним определение новых функций в модуле Exp. И посмотрим что у нас получилось:

*Exp> letenv a b =[(”1”, a), (”2”, b)]

*Exp> letexp =2 *(n 1 +n 2) -n 1

*Exp>runExp exp (env 1 2)

5

*Exp>runExp exp (env 10 5)

20

Так мы можем пользоваться функциями с окружением для того, чтобы читать значения из общего ис-

точника. Впрочем мы можем просто передавать окружение дополнительным аргументом и не пользоваться

монадами:

eval :: Env -> Exp -> Int

eval env x = casex of

Litn

->n

Negn

->negate $eval’ n

Adda b

->eval’ a +eval’ b

Mula b

->eval’ a +eval’ b

Varname

->value env name

whereeval’ =eval env

112 | Глава 7: Функторы и монады: примеры

7.4 Накопление результата

Рассмотрим по-подробнее тип Writer. Он выполняет задачу обратную к типу Reader. Когда мы пользова-

лись типом Reader, мы могли в любом месте функции извлекать данные из окружения. Теперь же мы будем

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «haskell-notes»

Представляем Вашему вниманию похожие книги на «haskell-notes» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «haskell-notes»

Обсуждение, отзывы о книге «haskell-notes» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x