OberonCore
https://forum.oberoncore.ru/

Несовместимость с процедурным типом
https://forum.oberoncore.ru/viewtopic.php?f=29&t=2421
Страница 1 из 1

Автор:  Роман М. [ Воскресенье, 07 Март, 2010 21:25 ]
Заголовок сообщения:  Несовместимость с процедурным типом

Код:

TYPE
   
   List* = POINTER TO RECORD (O.Object)
      FCount,
      FCapacity: INTEGER;
      FList: POINTER TO ARRAY OF O.Object;
   END;

   ListSortCompare* = PROCEDURE (Index1, Index2: INTEGER): INTEGER;
   ListSortExchange* = PROCEDURE (Index1, Index2: INTEGER);
   ListSort* = PROCEDURE (l, r: INTEGER; Compare: ListSortCompare; Exchange: ListSortExchange);
   
   PROCEDURE QuickSort (
         L, R : INTEGER;
         Compare: ListSortCompare;
         Exchange: ListSortExchange);
      VAR
         I, J: INTEGER;
         P, Q: INTEGER;
   BEGIN
      REPEAT
         I := L;
         J := R;
         P := (L + R) DIV 2;
         REPEAT
            WHILE Compare (P, I) > 0 DO INC(I) END;
            WHILE Compare (P, J) < 0 DO DEC(J) END;
            IF I <= J THEN
               Exchange (I, J);
               INC(I);
               DEC(J)
            END;
         UNTIL I > J;
         IF L < J THEN QuickSort (L, J, Compare, Exchange) END;
         L := I;
      UNTIL I >= R;
   END QuickSort;
   
   PROCEDURE (L: List) Sort*(sortList: ListSort; Compare: ListSortCompare), NEW;
   BEGIN
      sortList (0, L.FCount - 1, Compare, L.Exchange)
   END Sort;

В строке
sortList (0, L.FCount - 1, Compare, L.Exchange)
показывает сообщение о несовместимости типов.
Тобишь, L.Exchange не тождественен типу ListSortExchange. Или, иными словами,
PROCEDURE (L: List) Exchange* (Index1, Index2: INTEGER)
и
PROCEDURE (Index1, Index2: INTEGER)
разные типы.

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

Автор:  Александр Ильин [ Воскресенье, 07 Март, 2010 21:37 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Роман М. писал(а):
PROCEDURE (L: List) Exchange* (Index1, Index2: INTEGER)
и
PROCEDURE (Index1, Index2: INTEGER)
разные типы.
Естественно, списки параметров ведь разные.
Роман М. писал(а):
Каким же образом я могу представить процедурный тип иначе, чтобы я мог подставить его в sortList?
Убрать параметр (L: List) либо внести его в основной список параметров: PROCEDURE Exchange* (L: List; Index1, Index2: INTEGER)

Автор:  Роман М. [ Воскресенье, 07 Март, 2010 21:39 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Убрать я не могу - ведь это метод, расширяющий запись.

Автор:  Александр Ильин [ Воскресенье, 07 Март, 2010 22:41 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Роман М. писал(а):
Убрать я не могу - ведь это метод, расширяющий запись.
Тогда дурацкий вопрос вам: зачем вам И переопределяемый метод, И параметр в методе Sort (который, кстати, тоже переопределяемый)?

Автор:  Роман М. [ Воскресенье, 07 Март, 2010 22:53 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Дело в том, что я решил отступиться от метода быстрой сортировки, оставив только процедуру сравнения двух ячеек списка и процедуру обмена ячеек, чтобы можно было опробовать другой метод сортировки.
Обмен ячеек выполняется "встроенным" методом списка, а вот сравнение ячеек - неявно, поэтому должно производиться внешней процедурой.
Вот такие у меня соображения.

Автор:  Валерий Лаптев [ Воскресенье, 07 Март, 2010 22:56 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Цитата:
В строке
sortList (0, L.FCount - 1, Compare, L.Exchange)
показывает сообщение о несовместимости типов.
Тобишь, L.Exchange не тождественен типу ListSortExchange. Или, иными словами,
PROCEDURE (L: List) Exchange* (Index1, Index2: INTEGER)
и
PROCEDURE (Index1, Index2: INTEGER)
разные типы.

Ну дык это и в С++ тип метода не совпадает с типом функции с теми же параметрами. Только там этого не видно, а здесь налицо явный параметр.

Автор:  Роман М. [ Воскресенье, 07 Март, 2010 23:25 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Валерий Лаптев писал(а):
Только там этого не видно, а здесь налицо явный параметр.

Я мог бы использовать L.Exchange в процедуре QuickSort, если бы она являлась методом List.

Решил таки внести QuickSort как скрытый метод списка, который при желании можно переопределить другой функцией сортировки.
Код:
   PROCEDURE (L: List) QuickSort (
         l, r : INTEGER;
         Compare: ListSortCompare), NEW;
      VAR
         i, j: INTEGER;
         p, q: INTEGER;
   BEGIN
      REPEAT
         i := l;
         j := r;
         p := (l + r) DIV 2;
         REPEAT
            WHILE Compare (p, i) > 0 DO INC(i) END;
            WHILE Compare (p, j) < 0 DO DEC(j) END;
            IF i <= j THEN
               L.Exchange (i, j);
               INC(i);
               DEC(j)
            END;
         UNTIL i > j;
         IF i < j THEN L.QuickSort (l, j, Compare) END;
         l := i;
      UNTIL i >= r;
   END QuickSort;
   
   PROCEDURE (L: List) Sort*(Compare: ListSortCompare), NEW, EXTENSIBLE;
   BEGIN
      L.QuickSort (0, L.FCount - 1, Compare)
   END Sort;

Автор:  Валерий Лаптев [ Понедельник, 08 Март, 2010 09:45 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

В С++ вопрос совместимости типов функций и методов решается написанием оберток-функкторов вокруг указателей. У меня в книжке по ООП есть раздел "Как написать обобщенный алгоритм", где я достаточно подробно этот вопрос обсуждаю. Интересно, как это решить в КП?
Кстати, в stlном списке сортировка тоже собственная, реализована как метод класса list.

Автор:  Galkov [ Понедельник, 08 Март, 2010 12:02 ]
Заголовок сообщения:  Re: Несовместимость с процедурным типом

Александр Ильин писал(а):
Тогда дурацкий вопрос вам: зачем вам И переопределяемый метод, И параметр в методе Sort (который, кстати, тоже переопределяемый)?

У меня в голове сразу возникает куча, не менее дурацких - ответов
1) в задаче могут быть много разных списков. Например, столбцы некой матрицы. И каждый сортируется по своему критерию: числовой прядок, текстовый, как дата, и т.п..
2) таких "матриц" может быть несколько. Т.е., превращение метода в просто_функцию - не всегда в тему.

Про замену процедурного типа на абстрактный объект приемник_сообщений - я знаю.
Наслушался уже.
Просто function of object - выглядело бы гораздо естественней. И эффективнее

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/