Читаем Изучай Haskell во имя добра! полностью

Действие, которое производит блок do, будет всегда возвращать результирующее значение своего последнего действия. Вот почему мы используем функцию return, чтобы создать действие ввода-вывода, которое в действительности ничего не делает, а просто возвращает применение f result в качестве результата нового действия ввода-вывода. Взгляните на этот кусок кода:

main = do

   line <– getLine

   let line' = reverse line

   putStrLn $ "Вы сказали " ++ line' ++ " наоборот!"

   putStrLn $ "Да, вы точно сказали " ++ line' ++ " наоборот!"

У пользователя запрашивается строка, и мы отдаём её обратно пользователю, но в перевёрнутом виде. А вот как можно переписать это с использованием функции fmap:

main = do

   line <– fmap reverse getLine

   putStrLn $ "Вы сказали " ++ line ++ " наоборот!"

   putStrLn $ "Да, вы точно сказали " ++ line ++ " наоборот!"

Так же как можно отобразить Just "уфф" с помощью отображения fmap reverse, получая Just "ффу", мы можем отобразить и функцию getLine с помощью отображения fmap reverse. Функция getLine – это действие ввода-вывода, которое имеет тип IO String, и отображение его с помощью функции reverse даёт нам действие ввода-вывода, которое выйдет в реальный мир и получит строку, а затем применит функцию reverse к своему результату. Таким же образом, как мы можем применить функцию к тому, что находится внутри коробки Maybe, можно применить функцию и к тому, что находится внутри коробки IO, но она должна выйти в реальный мир, чтобы получить что-либо. Затем, когда мы привязываем результат к имени, используя запись <–, имя будет отражать результат, к которому уже применена функция reverse.

Действие ввода-вывода fmap (++"!") getLine ведёт себя в точности как функция getLine, за исключением того, что к её результату всегда добавляется строка "!" в конец!

Если бы функция fmap работала только с типом IO, она имела бы тип fmap :: (a –> b) –> IO a –> IO b. Функция fmap принимает функцию и действие ввода-вывода и возвращает новое действие ввода-вывода, похожее на старое, за исключением того, что к результату, содержащемуся в нём, применяется функция.

Предположим, вы связываете результат действия ввода-вывода с именем лишь для того, чтобы применить к нему функцию, а затем даёте очередному результату какое-то другое имя, – в таком случае подумайте над использованием функции fmap. Если вы хотите применить несколько функций к некоторым данным внутри функтора, то можете объявить свою функцию на верхнем уровне, создать анонимную функцию или, в идеале, использовать композицию функций:

import Data.Char

import Data.List

main = do

   line <– fmap (intersperse '-' . reverse . map toUpper) getLine

   putStrLn line

Вот что произойдёт, если мы сохраним этот код в файле fmapping_io.hs, скомпилируем, запустим и введём "Эй, привет":

$ ./fmapping_io

Эй, привет

Т-Е-В-И-Р-П- -,-Й-Э

Выражение intersperse '-' . reverse . map toUpper берёт строку, отображает её с помощью функции toUpper, применяет функцию reverse к этому результату, а затем применяет к нему выражение intersperse '-'. Это более красивый способ записи следующего кода:

(\xs –> intersperse '-' (reverse (map toUpper xs)))

<p>Функции в качестве функторов</p>

Другим экземпляром класса Functor, с которым мы всё время имели дело, является (–>) r. Стойте!.. Что, чёрт возьми, означает (–>) r? Тип функции r –> a может быть переписан в виде (–>) r a, так же как мы можем записать 2 + 3 в виде (+) 2 3. Когда мы воспринимаем его как (–>) r a, то (–>) представляется немного в другом свете. Это просто конструктор типа, который принимает два параметра типа, как это делает конструктор Either.

Но вспомните, что конструктор типа должен принимать в точности один параметр типа, чтобы его можно было сделать экземпляром класса Functor. Вот почему нельзя сделать конструктор (–>) экземпляром класса Functor; однако, если частично применить его до (–>) r, это не составит никаких проблем. Если бы синтаксис позволял частично применять конструкторы типов с помощью сечений – подобно тому как можно частично применить оператор +, выполнив (2+), что равнозначно (+) 2, – вы могли бы записать (–>) r как (r –>).

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных