Конспект лекций Рыбинск 2010





Скачать 450.1 Kb.
НазваниеКонспект лекций Рыбинск 2010
страница12/12
Дата публикации21.09.2013
Размер450.1 Kb.
ТипКонспект
100-bal.ru > Информатика > Конспект
1   ...   4   5   6   7   8   9   10   11   12

5.2Модули


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

Каждый модуль должен иметь вид:

[module <Имя> where]

<код>

Если необязательная часть опущена, то данный модуль не сможет быть использован из других модулей. Имя модуля, также как и типы данных, должно начинаться с прописной буквы, а также совпадать с именем файла.

Для получения доступа к определениям (функции, типы данных, классы) во внешних модулях, необходимо в самом начале программы описать их следующим образом:

[module <Имя> where]

import <модуль1>

...

import <модульN>

<остальной код>

После этого все определения из этих модулей становятся доступными в текущем модуле. Но если в текущем модуле определены функции или типы данных, совпадающие по имени с импортируемыми, либо если в разных подключаемых модулях окажутся одноименные функции или типы данных, то возникнет ошибка. Чтобы этого избежать, необходимо запретить использование таких определений из соответствующих модулей. Это делается следующим образом:

import <модуль> hiding (<скрываемые определения>)

Кроме того, при описании самого импортируемого модуля есть возможность управлять доступом к определениям. Для этого нужно перечислить доступные определения в скобках после имени модуля:

module <Имя>(<определения>) where <код>

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

В качестве примера можно привести программу из 3х модулей:

--Prog.hs

module Prog where

import Mod1

import Mod2 hiding(modfun)

--Mod1.hs

module Mod1(modfun) where

modfun = five * 2

five = 5

--Mod2.hs

module Mod2 where

modfun = 20

Из модуля Prog доступна функция modfun, определенная в модуле Mod1, но не доступна функция five.

6Классы и монады

6.1Классы


В Haskell'е поддерживается объектно-ориентированная парадигма. Но она немного отличается от привычной, принятой в других языках. Экземпляром класса является структура данных. Каждый класс предполагает описание некоторых функций для работы с типами данных, которые являются экземплярами этого класса.

Для определения класса используется следующая запись:

сlass [(<ограничения>) =>] <имя> <переменная типов> where <функции>

Переменная типов именует некий тип, который должен быть экземпляром этого класса. После слова where распологаются описания типов функций, а также выражение некоторых из этих функций через друг друга. С помощью этих выражений интерпретатор сможет сам определить часть функций экземпляра класса, если задана другая часть. Ограничения – это определение того, что экземпляр нашего класса также должен быть экземпляром перечисленных здесь классов. Это, своего рода, наследование. Рассмотрим пример:

class Eq a where

(==), (/=) :: a -> a -> Bool

x == y = not (x/=y)

x /= y = not (x==y)

Класс Eq является классом сравнимых типов. Для каждого экземпляра этого класса должны быть определены функции равенства и неравенства. Вторая строка означает, что функции (==) и (/=) должны принимать два аргумента типа a и возвращать объект типа Bool, то есть True или False.

Следующие строчки в определении класса говорят о том, что если определена функция (/=), то функция (==) определяется через нее соответствующим образом, и наоборот. Благодаря этому программисту достаточно определить только функцию сравнения на равенство (или неравенство), а другую функцию интерпретатор определит сам.

Еще пример определения класса, но с наследованием:

class Eq a => MyClass a where

myFunc :: [a] -> a -> Int

Когда класс определен, можно объявить какой-либо тип данных экземпляром этого класса:

instance MyClass Double where

myFunc [] _ = 0

myFunc (x:xs) z

|x==z = 1 + myFunc xs z

|otherwise = myFunc xs z

Таким образом мы объявляем стандартный тип Double экземпляром нашего класса MyClass и определяем функцию myFunc как функцию, вычисляющую количество элементов в первом аргументе, равных второму аргументу функции.

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

test = myFunc x 2 where

x :: [Double]

x = [1,2,3,2,1]
Классы часто используются при описании функций с полиморфными параметрами. Например, если нужно описать функцию, использующую операцию сравнения, для многих типов данных, необходимо указать, что ее параметры, которые участвуют в сравнении, должны быть типа класса Eq, который гарантирует реализацию соответствующей функции.
Когда программист описывает свою структуру данных, она не принадлежит ни к какому из классов. При необходимости программист должен реализовать соответствующие функции для своей структуры и указать ее принадлежность к классу. Например, ранее описанную структуру данных Tree можно объявить экземпляром класса Show, для того что бы интерпретатор мог выводить ее на экран, не прибегая к ручному вызову функции showtree. Для этого напишем:

instance Show a => Show (Tree a) where

show = showtree

После этого при получении интерпретатором результата типа Tree он сможет вывести его на экран, а также любая другая функция сможет перевести объект типа Tree в строковый вид с помощью функции show.

Кроме того, существует еще один способ объявления принадлежности типа к классу. Он более прост, но не всегда может удовлетворить потребности программиста. Он заключается в перечислении нужных классов сразу при объявлении структуры:

data <имя> = <значение1> | <значение2> | ... | <значениеN> deriving (<класс1>,<класс2>,...,<классM>)

Здесь необходимые функции будут при возможности выведены автоматически. Так, например, определим наш тип Tree экземплярам класса Eq, для того чтобы деревья можно было сравнивать между собой.

data Tree a = Nil | Tree a (Tree a) (Tree a)

deriving (Eq)

Теперь возможно сравнение деревьев операцией “==”, и позволяет использовать их в функциях, требующих это.

6.2Ввод-вывод



Возможно написать побольше про монады
Как было сказано выше, Haskell — чистый функциональный язык программирования, то есть функции в нем не могут иметь побочных эффектов, и порядок вычисления функций не определен. Но в некоторых случаях без этого обойтись нельзя. К таким случаям можно отнести работу с пользователем, с файлами, с базами данных и так далее. В языке Haskell предусмотрено задание таких функций с помощью монад — особых контейнерных классов. В изучении Haskell'а монады считается самой трудной частью, поэтому начнем сразу с примеров. Объяснение некоторых вещей будут опущены, чтобы не запутать читателя. Рассмотрим следующий пример:

main = do

putStrLn "Hello world!"

putStrLn "Good bye world!"

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

При использовании нотации do программирование «нечистых» функций с помощью монад сводится практически к привычному императивному программированию.

Каждая следующая строчка должна быть функцией специального типа — монадического типа. В случае работы с вводом-выводом это тип (IO a).

Для работы с командной строкой используются следующие функции:

putChar :: Char -> IO () -- вывод символа

putStr :: String -> IO () -- вывод строки

putStrLn :: String -> IO () -- вывод строки с переходом на новую строку

getChar :: IO Char -- прочитать символ

getLine :: IO String -- прочитать строку

IO a — это монадический тип ввода-вывода, скрывающий побочные эффекты в себе. Тип IO String означает, что функция вернет результат, содержащий строку, а IO () означает, что функция возвращает результат, ничего не содержащий, смысл ее вызова только в побочных эффектах (например, вывод). Пример:

main = do

putStrLn "What is you name?"

name <- getLine

putStrLn ("Hi, " ++ name ++ "!")

Здесь появилось «присваивание». По аналогии с императивными языками можно сказать, что в строке

name <- getLine

произошло присваивание переменной name результата функции getLine. Но, как мы знаем, в Haskell'е нет переменных и значит и присваиваний. В данном случае произошло создание некоторого объекта с именем name, значение которого равно результату вычисления функции getLine. То есть, если после этого написать еще раз

name <- getLine

то создастся новый объект, имя которого перекроет предыдущий.

Таким образом выполняется извлечение результатов монадических функций. Для того чтобы задать подобным образом «переменные» значениями обыкновенных функций используется упрощенная нотация let:

let name = "John"

Ветвление вычислительного процесса осуществляется с помощью тех же if then else и case:

main = do

putStrLn "What is you name?"

name <- getLine

case name of

"GHC" -> putStrLn "No! I am GHC!"

_ -> putStrLn ("Hi, " ++ name ++ "!")

Если ветвление должно состоять из нескольких функций, то используется ключевое слово do:

main = do

putStrLn "What is you name?"

name <- getLine

case name of

"GHC" -> do

putStrLn "No! I am GHC!"

main

_ -> putStrLn ("Hi, " ++ name ++ "!")
Циклы осуществляются с помощью рекурсии, как показано выше, или с помощью специальных функций (реализованных также рекурсивно). К таким функциям относится функция mapM_. Принцип ее работы аналогичен функции map для списков — она применяет монадическую функцию ко всем элементам списка и последовательно выполняет их. Пример:

writeDigit x = do

putStr " "

putStr (show x)

main = do

putStr "Digits:"

mapM_ writeDigit [0..9]

putStrLn ""

7Примеры


Привести различные примеры (деревья поиска, AVL дерево, еще что-нибудь)

Заключение


Заключение

Список использованных источников



1   ...   4   5   6   7   8   9   10   11   12

Похожие:

Конспект лекций Рыбинск 2010 iconМестного самоуправления городского округа город рыбинск
В соответствии с Федеральным законом от 02. 03. 2007 n 25-фз "О муниципальной службе в Российской Федерации", законодательством о...
Конспект лекций Рыбинск 2010 iconОтчет главы городского округа город Рыбинск
«Об общих принципах организации местного самоуправления в Российской Федерации» на основе информации структурных подразделений и...
Конспект лекций Рыбинск 2010 iconКонспект лекций по курсу сд. Ф корпоративные информационные системы
Д. В. Колесов, Р. Д. Маш, И. Н. Беляев «Биология. Человек», Изд-во «Дрофа», Москва, 2010
Конспект лекций Рыбинск 2010 iconС. П. Филин Концепции современного естествознания: конспект лекций
Конспект лекций соответствует требованиям Государственного образовательного стандарта высшего профессионального образования РФ и...
Конспект лекций Рыбинск 2010 iconКонспект лекций раскрывает содержание и структуру учебной дисциплины...
Налоговое право : конспект лекций / сост доцент Р. В. Бобринев; Кузбасский институт экономики и права. – Кемерово, 2011 – 144 с
Конспект лекций Рыбинск 2010 iconКонспект лекций по дисциплине: теория систем и системный анализ санкт-Петербург...
Выбор показателя эффективности, математическая постановка задачи
Конспект лекций Рыбинск 2010 iconКонспект лекций по философии Часть 1 Античная философия Новосибирск...
Савостьянов А. Н. Конспект лекций по философии / Новосиб гос ун-т. Новосибирск, 2007. Ч. Античная философия. 68 с
Конспект лекций Рыбинск 2010 iconКонспект лекций по курсу хозяйственного права тема Понятие хозяйственного права
Кафедра Истории, социологии и права Назаров Андрей Александрович конспект лекций по курсу хозяйственного права
Конспект лекций Рыбинск 2010 iconКонспект лекций по высшей математике. В 2 частях. Часть М.: Айрис-пресс,...
Баранова Е. С., Васильева Н. В., Федотов В. Л. Практическое пособие по высшей математике. Типовые расчеты. Учебное пособие. — Спб:...
Конспект лекций Рыбинск 2010 iconОпорный конспект лекций Основные понятия, термины, законы, схемы...
Л. Н. Блинов, Н. Н. Ролле. Экология: опорный конспект лекций. Основные понятия, термины, законы, схемы. Спб.: Изд. Спбгпу. 2005....
Конспект лекций Рыбинск 2010 iconКонспект лекций Владимира Климентьева по истории философии, отредактированный...
Рекомендовано Министерством общего и профессионального образования Российской федерации в качестве учебника для студентов высших...
Конспект лекций Рыбинск 2010 iconТеория организации Конспект лекций для студентов специальности «Менеджмент организации»
Макарова н. Н. Теория организации. Конспект лекций с практическими заданиями для студентов специальности "Менеджмент организации....
Конспект лекций Рыбинск 2010 iconПисьменный Д. Т. Конспект лекций по теории вероятностей, математической...
Письменный Д. Т. Конспект лекций по теории вероятностей, математической статистике и случайным процессам. 3-е изд. М.: Айрис-пресс,...
Конспект лекций Рыбинск 2010 iconКонспект лекций

Конспект лекций Рыбинск 2010 iconКонспект лекций по дисциплине правовое регулирование маркетинговой деятельности
Опорный конспект лекций по дисциплине правовое регулирование маркетинговой деятельности
Конспект лекций Рыбинск 2010 iconКонспект лекций по дисциплине методика самостоятельной работы студента...
Отсутствие таких навыков приводит к тому, что учащиеся чувствуют беспомощность и растерянность при необходимости самостоятельно подготовить...


Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
100-bal.ru
Поиск