Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[11]

type PointART[PointRep] =

{rnkpoint: (Real « Real) -> PointRep. x-coord: PointRep -> Real, y-coord: PointRep -> Real )

Экзистенциональный тип Point может быть определен в терминах PointWRT при помощи экзистенциональной абстракции по отношению к PointRep.

type Point = BPointRep. PointWRT[PointRep]

Отношение между представления-зависимыми операциями и соответствующими асбстрактными типами данных становится более понятным ,когда мы проиллюстрируемпроцесс абстракции для некоторых специфичных представлений точек. Давай те определим пакет декартовой точки , в котором представление точки это пара децствительных чисел ,операции над которыми mkpoint , x-coord , y-coord выглядят так:

value cartesianPointOps =

{rnkpoint = fun (x:Real, y:Real) (x,y), x-coord = fun (p: Real * Real) fstfp), y-coord = fun (p: Real * Real) snd{p)

}

Пакет с представлением точки Real*Real и с реализаций операций над точками может быть опеределен следующим образом:

value cartesianDointPackage =

pack [PointRep = Real * Real in PointWRT[PointRep]] cartesian PointOps

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

value polarPointPackage =

pack[PointRep = Real v Real in PointWRT [PointRep]] {rnkpoint = fun (x:Real, у:Real)... , x-coord = fun (p: Real x Real)..., y-coord = fun (p: Real v Real)...

Этипримеры иллюстрируют как пакеты реализуцбт абстракции данных путем сокрытия и представления данных и реаллизации операторов.Пакеты декартовых и полярных точек имеют один и тот же экзистенциональный тип Point , сипользуют один и тот же параметрический тип PointWRT[PointRep] для определения структуры операций над точками и имеют один и тот же тип для представления данных. Они только отдичаются содержпнием пакета ,который определяет реализацию функции.В общем случае экзистенциональные типы влияют на то ,чтоюы пакеты таких типов имели одинаковую структуру для операций.Но и типы для представления внутренних данных и реализация операций может отличаться для разных реализаций абстракнтных типов данных.

Абстрактный тип данных спакетированный со своими операциями , так же как Point ,это также простой пример модуля.В общем случае модули могут импортировать другие модули , или могут быть параметрихированными по отнозения к други модулям.

Парметрические модули могут быть представлены как функции над экзистенциональнымии типами. Здесь приведен пример того как Point пакет может быть расширен еще одной операцией add.Вместо того чтоюбы делать это расширение для


конкретного пакета Point , мы напишем процедуру для расщирения любого паекта Point над неизвестным пресдтавлением Point. Вспомниет ,что & это оператор конкантенации типа запись:

type ExtendedPointWRT[PointRep] =

PointWRT[PointRep] & {add: {PointRep w PointRep) -» PointRep}

type Extended Point = 3PointRep. Extend edPointWRT[PointRep]

value extendPointPackage = fun (pointPackage: Point)

open pointPackage as p [PointRep] in

pack[PointRep= PointRep in ExtendedPointWRT[PointRep]] p &

{add = fun (a:PointRep, b:PointRep) p .m к ро int( p. x-coord(a)+p. x-coord [b), p .y-coo rd (a)+p .x- coo rd (b})

}

value extend ed Cartesian PointPackage =

exte nd Po intP a ckag e(cartesian Po intP a ckag e)

value extendedPolarPointPackage =

exte nd Po intP a ckag e(polarP oi ntPackage)

Сейчас мы вернемся к модулю Point и покажем как другие можули могут быть построены на его верхушкею. В частности мы посроем модули Circle и Rectangle на верхушке модуля Point и потом определим модуль Picture ,котрроый использует и Circle и Rectagle.Люббые экземпляры Point могут быть основаны на произвольных представлениях данных , мы должны удостоверится ,что круги и прямоугольники основаны на одинаковых представалениях Point , если мы хотим ,чтобы они взаимодействовали.

Пакет круг предоставляет опрерации для создания круга из точки (центр) и действительного числа(радиус) и операции которые возвращают центр и радиус круга. Операция difГ(расстояние между центрами двух кругов ) также определена. Два параметра diff это круги основанные на одинаковых представлениях Point. Пакет круг также предоставляет пакет точка , чтобы позволять иметь доступ к операциям надд точками.

type CircleWRT2[CircleRep,PointRep] = (pointPackage: PointWRT[PointRep], mkcircle: (PointRep * Real) -> CircleRep, center: CircleRep -> PointRep, radius: CircleRep -» Real, diff: (CircleRep * CircleRep) -» Real

}

type CircleWRTI [PointRep] =

3C i rcl e Re p. CircleW RT2[C ire leRep, Po intRe p]

type Circle = 3PointRep. CircleWRTI [PointRep]

type CircleModule =

VPointRep. PointWRT[PointRep] -» CircleWRTI [PointRep]

value CircleModule : CircleModule = all[PointRep]


fun (p: PointWRT[PointRep])

pack[CircleRep = PointRep у Real in С ircleWRT2 [CircleRep .Point Rep]] {pointPackage = p,

mkcircle = fun (ni:PointRep,r:Real) (ni,r),

center = fun (c: PointRep * Real) fst(c),

radius = fun (c: PointRep у Real) snd(c),

diff = fun (c1: PointRep у Real, c2: PointRep у Real)

letpl = fst[d}

and p2 = fat(c2)

in sqrt[(p.x-coord(p1} - p.x-coord<p2))**2+ (p.y-coond(pl) - p .y-coord (p 2 })"2)

}

Мы теперь можем постоить некотрорый пакет круг , применив circleModule к различным пакетам точкам.Мы можем также определить различные версии circleModule основанные на различных представлениях круга и все это можно применить к различным пакетам точкам ,чтобы получить пакеты круги.Здесь мы применяем circleModule к cartesianPointPackage и к polarPointPackage для получения пакетов декартовых и полярных точек.

value cartesian Circle Package =

open cartesianPointPackage as p [Rep] in

pack[PointRep = Rep in С ire leWRTI [PointRep]] circleModule[Rep](p)

value polarCirdePackage =

open polarPointPackage as p [Rep] in

pack[PointRep = Rep in С ire leWRTI [PointRep]] circleModule[Rep](p)

Чтобы испльзовать пакеты точек мы долоны спвар их открыть.Мы должны открыть их два раза ,чтобы(заметьте что тип Circle имеет двойную экзистенциональную квантификацию) для связывания PointRep и CircleRep с представлениями точки и круга используемых в пакете. Здесь мы используем сокрашщенную форму open ,которая эквивалентна последовательным открытиям.

open cartesian Circle Package as с [PointRep] [CircleRep] in ... c.mkcircle(c.pointPackage.mkpoint(3,4),5)...

Прямоугольник опредделяется двумя точками , верхняя левая и правая нижняя. Определение можулля прямоугольника очень похоже на определение модуо\ля круга. В добавление к жтотму мы должны удостоверится ,что две точки определяющие прямоугольник основаны на одинаковом представлении Point.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13]