haskell-notes

для фиксации типа первого аргумента:

q = f $ x ‘asTypeOf‘ var

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

И другие удобства и украшения

Стоит упомянуть несколько расширений. Они лёгкие для понимания, в основном служат украшению

записи или для сокращения рутинного кода.

Директива deriving может использоваться только с несколькими стандартными классами, но если мы

определили тип-обёртку через newtype или просто синоним, то мы можем очень просто определить новый

тип экземпляром любого класса, который доступен завёрнутому типу. Как раз для этого существует расши-

рение GeneralizedNewtypeDeriving:

newtype MyDouble = MyDouble Double

deriving (Show, Eq, Enum, Ord, Num, Fractional, Floating)

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

регруженных строках, как раз для этого существует расширение OverloadedStrings. При этом за обычной

записью строк может скрываться любой тип из класса:

class IsString a where

fromString :: String -> a

Расширение TypeOperators позволяет определять инфиксные имена не только для конструкторов типов,

но и для самих типов, синонимов типов и даже классов:

data a :+: b = Left a | Right b

17.3 Краткое содержание

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

является полигоном для испытания самых разнообразных идей. Это экспериментальный язык. Но в практиче-

ских целях в 1998 году был зафиксирован стандарт языка, его обычно называют Haskell98. Любое расшире-

ние подключается с помощью специальной прагмы Language. Новый стандарт Haskell Prime включит в себя

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

конструкций, которые, возможно, облегчают написание программ.

17.4 Упражнения

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

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

вам в чужом коде или в библиотеках.

264 | Глава 17: Дополнительные возможности

Глава 18

Средства разработки

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

устанавливать и создавать библиотеки, писать документацию.

18.1 Пакеты

В Haskell есть ещё один уровень организации данных, мы можем объединять модули в пакеты (package).

Также как и модули пакеты могут зависеть от других пакетов, если они пользуются модулями их этих па-

кетов. Одним пакетом мы уже пользовались и довольно часто, это пакет base, который содержит все стан-

дартные модули, например такие как Prelude, Control.Applicative или Data.Function. Для создания и

установки пакетов существует приложение cabal. Оно определяет протокол организации и распростране-

ния модулей Haskell.

Создание пакетов

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

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

поместить в одну директорию с src два файла:

имяПакета. cabal – файл с описанием пакета.

Setup. hs – файл с инструкциями по установке пакета

.cabal

Посмотрим на простейший файл с описанием библиотеки, этот файл находится в одной директории с

той директорией, в которой содержатся все модули приложения и имеет расширение . cabal:

Name

: Foo

Version

: 1.0

Library

builddepends

: base

exposedmodules

: Foo

Сначала идут свойства пакета. Общий формат определения свойства:

ИмяСвойства : Значение

В примере мы указали имя пакета Foo, и версию 1.0. После того, как мы указали все свойства, мы опре-

деляем будет наш пакет библиотекой или исполняемой программой или возможно он будет и тем и другим.

Если пакет будет библиотекой, то мы помещаем за набором атрибутов слово Library, а если это исполняе-

мая программа, то мы помещаем слово Executable, после мы пишем описание модулей пакета, зависимости

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

кой же как и в самом начале файла. Сначала идёт зарезервированное слово-атрибут, затем через двоеточие

следует значение. Обратите внимание на отступы за словом Library, они обязательны и сделаны с помощью

пробелов, cabal не воспринимает табуляцию.

Файл . cabal может содержать комментарии, они делаются также как и в Haskell, закомментированная

строка начинается с двойного тире.

| 265

Setup.hs

Файл Setup. hs содержит информацию о том как устанавливается библиотека. При установке могут ис-

пользоваться другие программы и библиотеки. Пока мы будем пользоваться простейшим случаем:

import Distribution.Simple

main = defaultMain

Этот файл позволяет нам создавать библиотеки и приложения, которые созданы только с помощью

Haskell. Это не так уж и мало!

Создаём библиотеки

Типичный файл . cabal для библиотеки выглядит так:

Name:

pinocchio

Version:

1.1. 1

Cabal-Version:

>= 1.2

License:

BSD3

License-File:

LICENSE

Author:

Mister Geppetto

Homepage:

http://pinocchio. sourceforge. net/

Category:

AI

Synopsis:

Tools for creation of woodcrafted robots

Build-Type:

Simple

Library

Build-Depends: base

Hs-Source-Dirs: src/

Exposed-modules:

Wood.Robot.Act, Wood.Robot.Percept, Wood.Robot.Think

Other-Modules:

Wood.Robot.Internals

Этим файлом мы описали библиотеку с именем pinocchio, версия 1.1.1, она использует версию cabal

не ниже 1.2. Библиотека выпущена под лицензией BSD3. Файл с лицензией находится в текущей директо-

рии под именем LICENSE. Автор библиотеки Mister Geppetto. Подробнее узнать о библиотеке можно на её

домашней странице http://pinocchio. sourceforge. net/. Атрибут Category указывает на широкую отрасль

знаний, к которой принадлежит наша библиотека. В данном случае мы описываем библиотеку для построе-

ния роботов из дерева, об этом мы пишем в атрибуте Synopsis (краткое описание), поэтому наша библиоте-

ка принадлежит к категории искусственный интеллект или сокращённо AI. Последний атрибут Build-Type

указывает на тип сборки пакета. Мы будем пользоваться значением Simple, который соответствует сборке с

помощью простейшего файла Setup. hs, который мы рассмотрели в предыдущем разделе.

После описания пакета, идёт слово Library, ведь мы создаём библиотеку. Далее в атрибуте Build-

Depends

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

своей библиотеке. В данном случае мы пользовались лишь стандартной библиотекой base. В атрибуте hs

sourcedirs мы указываем, где искать директорию с исходным кодом библиотеки. Затем мы указываем три

внешних модуля, они будут доступны пользователю после установки библиотеки (атрибут Exposed-Modules),

и внутренние скрытые модули (атрибут Other-Modules).

Создаём исполняемые программы

Типичный файл . cabal для исполняемой программы:

Name:

micro

Version:

0.0

Cabal-Version:

>= 1.2

License:

BSD3

Author:

Tony Reeds

Synopsis:

Small programming language

Build-Type:

Simple

Executable micro

266 | Глава 18: Средства разработки

Build-Depends:

base, parsec

Main-Is:

Main. hs

Hs-Source-Dirs: micro

Executable microrepl

Main-Is:

Main. hs

Build-Depends:

base, parsec

Hs-Source-Dirs: repl

Other-Modules:

Utils

В этом файле мы описываем две программы. Компилятор языка и интерпретатор языка micro. Если срав-

Читай продолжение на следующей странице
Добавить комментарии