Главная » Haskell » Простые структуры

0

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

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

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

В языке Haskell объединение значений различных  типов в единый объект производится при помощи перечисления по порядку типов значений, которые хранятся в соответствующем алгебраическом типе данных. Само собой разумеется, что порядок перечисления типов внутренних значений важен.

Например, в каком-либо  приложении, работающим с  геометрическими фигурами  в  трёхмерном пространстве, имеется  необходимость  определить тип для представления  точки  пространства.  Это можно сделать следующим образом:

data  Point3D

= Point3D  Float Float Float

Эта запись означает то, что алгебраический тип данных Point3D имеет один конструктор Point3D (совершенно неважно, что эти программные сущности называются одинаково —  их  наименования  находятся в разных пространствах имён), который «прячет» внутри себя три значения типа Float, каждое из которых представляет собой координату точки по одной из осей трёхмерного  пространства.

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

data  Point2D

= Point2D  Int Int Color

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

shift (Point3D   x  y  z) dx dy dz = Point3D  (x + dx)  (y +  dy)  (z + dz)

Как  видно, первый параметр функции является точкой в  трёхмерном пространстве. Для доступа к её  внутренней  структуре  в заголовке  функции она непосредственно расписана в виде указания на конструктор данных и соответствующие поля структуры, при этом сами поля получают определённые имена, которые действительны только внутри функции. Если же необходимости в доступе нет, то всю структуру можно назвать одним именем (именем параметра функции). Например, для сдвига точки в трёхмерном пространстве только по одной из осей можно воспользоваться следующим набором функций:

shiftX p dx =  shift p dx 0 0 shiftY p dy =  shift p 0 dy 0 shiftZ p dz =  shift p 0 0 dz

Более того, если в функции есть необходимость доступа только к некоторым

элементам структуры, то можно называть именно их, оставляя остальные анонимными. Для этого используется маска  подстановки  «любое значение»,  которая в языке Haskell записывается символом подчёркивания (_). Так, к примеру, функции для получения координат заданной точки в трёхмерном пространстве выглядят так:

getX  (Point3D  x  _  _)  = x getY  (Point3D   _ y  _)  = y getZ  (Point3D   _ _  z) = z

Остаётся отметить, что при объявлении элементов структур можно ограни-

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

Флажок  строгости имеет вид (!)  и ставится непосредственно  перед типом элемента структуры. Например:

data  Point3D

= Point3D  !Float !Float !Float

Источник: Душкин Р. В., Справочник по языку Haskell. М.: ДМК Пресс, 2008. 544 с., ил.

По теме:

  • Комментарии