Я бы не стал завязываться на убогие диапазоны. А в настоящих рефайнмент-типах должна быть проверка на выход за диапазон. Это можно реализовать на базе структур и перегруженных операций, включая implicit
type posnumber = integer where value > 0;
Ну всё же с Power
это не пройдёт, получается что у возвращаемого значения будет меняться тип и определить его на этапе компиляции не получится если второе число не константное. Тут единственный вариант это делать перезагрузку операции по случаю, можно разве что добавить функцию IntPow
, как полностью отдельную. А реализовать диапазонные типы не сложно, но опять же смысла в них сильно большого не будет потому что выбор подпрограммы с ними никак не заменить.
Хотелось бы иметь две процедуры для реализованного подмножества операций с матрицами:
procedure SortByRow<T>(a:array[,] of T; row:integer; descending:boolean:=False);
procedure SortByCol<T>(a:array[,] of T; col:integer; descending:boolean:=False);
Сортировка двумерного массива встречается в задачах не так уж редко, а её реализация с прицелом на стиль функционального программирования выглядит на мой малопросвещенный взгляд достаточно некрасиво, что портит общий вид решения (по крайней мере, мне не удалось сделать привлекательный код). У нас уже есть Sort для одномерных массивов, почему бы не сделать подобное счастье для двумерных?
В плане реализации, быть может, имеет смысл получить уже имеющейся сортировкой одномерной последовательности нужный порядок ключей, а затем произвести необходимые перестановки строк (столбцов), либо выполнить копирование через промежуточную матрицу. Копирование проще в реализации, а матрицы размером 1000000х1000000 вряд ли кто-то будет сортировать. С другой стороны, решение задачи об оптимальном количестве перестановок в соответствии с ключами - это красиво.
Собственно, я пробную реализацию написал, вроде не самая плохая
procedure SortByRow<T>(a:array[,] of T; row:integer; descending:boolean:=False);
begin
if descending then begin
var b:=a.Row(row).Select((v,i)->(v,i)).OrderByDescending(q->q[0])
.Select(q->q[1]).ToArray;
for var i:=0 to a.ColCount-2 do begin
var j:=b[i];
a.SwapCols(i,j);
b[b.IndexOf(i,i)]:=j;
end
end
else begin
var b:=a.Row(row).Select((v,i)->(v,i)).OrderBy(q->q[0])
.Select(q->q[1]).ToArray;
for var i:=0 to a.ColCount-2 do begin
var j:=b[i];
a.SwapCols(i,j);
b[b.IndexOf(i,i)]:=j;
end
end;
end;
begin
var M:=MatrRandom(5,6,1,9);
M.Println(2);
Writeln(2*M.ColCount*'-');
SortByRow(M,2,True);
M.Println(2)
end.
Объединить две ветки не смог: ругается на возникающую несовместимость типов.
А можно пример кода вызывающий ошибку? Он ведь не должен ругаться…
procedure SortByRow<T>(a:array[,] of T; row:integer; descending:boolean:=False);
begin
var b:array of T;
if descending then
b:=a.Row(row).Select((v,i)->(v,i)).OrderByDescending(q->q[0])
.Select(q->q[1]).ToArray
else
b:=a.Row(row).Select((v,i)->(v,i)).OrderBy(q->q[0])
.Select(q->q[1]).ToArray;
for var i:=0 to a.ColCount-2 do begin
var j:=b[i];
a.SwapCols(i,j);
b[b.IndexOf(i,i)]:=j;
end
end;
SortByRow.pas(6) : Нельзя преобразовать тип array of integer к array of T
Т.е. при инстанцировании происходит замена обобщенного класса Т в заголовке процедуры, а в теле не меняется. Попытка написать тип Т в объявлении b как < T > или &< T > тоже безуспешна.
Проходит только так, но это извращение:
var b:=a.Row(row).Select((v,i)->(v,i)).OrderBy(q->q[0])
.Select(q->q[1]).ToArray;
if descending then
b:=a.Row(row).Select((v,i)->(v,i)).OrderByDescending(q->q[0])
.Select(q->q[1]).ToArray;
procedure SortByRow<T>(a:array[,] of T; row:integer; descending:boolean:=False);
begin
var b:=descending?
a.Row(row).Select((v,i)->(v,i)).OrderByDescending(q->q[0]).Select(q->q[1]).ToArray:
a.Row(row).Select((v,i)->(v,i)).OrderBy(q->q[0]).Select(q->q[1]).ToArray;
for var i:=0 to a.ColCount-2 do begin
var j:=b[i];
a.SwapCols(i,j);
b[b.IndexOf(i,i)]:=j;
end
end;
Спасибо, вариант, конечно. Но хотелось бы понять, как поступать в общем случае…
Это конечно да, но я не сильно понял как это работает, можете привести более простой пример?
Что - “это”? Инстанцирование? Работа с обобщенным типом? Я тоже не сильно в нем разбираюсь - все исключительно по системе Справки.
— Скажи мне, о Волька! Что означает слово «балда»?
— Понимаешь... Ну это, вроде как мудрец.
Видимо, бывают дни, когда писать программы противопоказано. Какой тут тип T, когда получается всегда integer? Вот и получаешься сам себе злобный буратино…
P.S. Попутно выяснилось, что если использовать в процедуре не массив, а список, получается выигрыш во времени исполнения 4-5%.
Окончательно фрагмент кода;
var b:=descending ?
a.Row(row).Select((v,i)->(v,i)).OrderByDescending(q->q[0])
.Select(q->q[1]).ToList :
a.Row(row).Select((v,i)->(v,i)).OrderBy(q->q[0])
.Select(q->q[1]).ToList;
Здравствуйте. Начну с начала. Я учусь на программиста. Я - незрячий пользователь компьютера и пользуюсь программами экранного доступа - скринридерами. Этот паскаль хорош, но он озвучивается неочень хорошо. Во-первых, редактор: 1. выделение текста не озвучивается, т.е. при движении по тексту комбинацией shift+стрелки скринридер молчит. 2. Может получиться так, что я двигаюсь по редактору, но в текста не слышу, т.е. произносится фраза “пусто”, хотя это не так. Вроде по редактору все. Во-вторых, горячие клавиши: они вроде есть, но ни в меню, ни в справке, да вообще нигде о них не говорится. В третих, возможность создавать оконные приложения: возможность-то есть, но, к сожалению, не для нас. Вообще без комментариев. Вывод печальный: среда класная, но не для нас. На сегодняшний день получается, что сред для работы в паскале хватает, но ни одна нормально не озвучивается, тоесть, нам приходится писать приложения в обычном блокноте, потом это дело открывать в среде и уже там смотреть, есть ли ошибки в коде или нет. Удобно ли это? не думаю. Потери во времени? большие, особенно если ошибок много и если учитывать доступность того же редактора. Просьба следующая: по возможности адаптировать систему PascalABCNET и под такую группу пользователей: поправить или заменить редактор, снабдить среду горячими клавишами такими, как переход в окно редактирования, переход в окно выполнения и т.д., сделать возможным создание проекта, в общем, сделать интерфейс среды мпо возможности максимально доступным. PS Может где-то коряво выразился, тут уж прошу прощения. Спасибо.
@admin Предлагаю несколько новых шорткатов для среды:
Меню “Файл”
- Новый проект Ctrl + Alt + N
- Открыть проект Ctrl + Alt + O
- Сохранить всё Ctrl + Alt + S
- Закрыть Ctrl + W
- Закрыть всё, кроме текущего Ctrl + Alt + W
Меню “Правка”
- Найти далее F3 (вместо Ctrl + L)
- Найти ранее Shift + F3 (новая возможность)
- Удалить все закладки Ctrl + Shift + F2
Меню “Вид”
- Окно вывода Alt + 1
- Список ошибок Alt + 2
- Сообщения компилятора Alt + 3
- Результат поиска символов Alt + 4
- Локальные переменные Alt + 5
- Просмотр выражений Alt + 6
- Окно дизассемблирования Alt + 7
- Панель навигации по коду Alt + 0
Меню “Программа”
- Параметры командной строки… Alt + F10
- Шаг с выходом из подпрограммы F6
Меню “Сервис”
- Настройки… F10
- Перейти к реализации Ctrl + Shift + Enter
- Сгенерировать реализацию Ctrl + Shift + I (от англ. ‘Implementation’)
- Найти все ссылки Alt + Shift + F
Меню “Модули”
- Сообщить об ошибке Alt + F1
function GBI<T>(Self:^T):byte; extensionmethod;
begin
end;
begin
end.
Program2.pas(1) : Нельзя расширять этот тип
Можно пожалуйста более содержательную ошибку?
Куда уж более содержательно
Ну смотрите, к примеру тут:
function f1: array[1..2] of byte;
begin
end;
begin end.
Program2.pas(1) : Тип параметра или возвращаемого значения не может быть описанием записи или описанием массива с границами
Объясняется что именно не может быть возвращающим значением. А в предыдущем случае сказано лишь “так нельзя”.
По горячим клавишам: горячки хорошие. Мне понравились. Хотелось бы, чтобы горячки были прописаны в справке пунктом “горячие клавиши” и хотелось бы, чтобы все комбинации клавиш были видны в меню, например, если я в дельфи 7 делаю меню и присваиваю пункту меню горячку, то потом скринридер мне ее читает. Например: “новый ctrl+n”, “открыть ctrl+o” и т.д. А будет ли все остальное? ну не все, хотя бы нормальное озвучивание редактора. Было бы отлично.
Хотелось бы узнать (и не мне одному, судя по всему), как обстоят дела с пространствами имён? Вроде бы всё компилируется по приведённым примерам, но в dll нет никаких следов пространств. Справка по этому вопросу вообще молчит…
Да справка то ладно, он и так дырявая, но вот то что на сайте об этом ничего это уже странно. Когда добавляют что то типа срезов - на pascalabc.net об этом сообщают.