Есть ли в Free Pascal переменные типа, такие как Haskell?

Haskell позволяет вам определять такие функции, как three, которые принимают элемент типа a и возвращают список элементов, повторяющихся три раза, для любого типа данных a.

thrice :: a -> [a]
thrice x = [x, x, x]

Разрешает ли Free Pascal переменные типа? Если нет, есть ли другой способ сделать это в Free Pascal?


person mcandre    schedule 17.10.2011    source источник
comment
Free Pascal имеет переменные типа в своих дженериках (сравнимых с шаблонами C++).   -  person    schedule 18.10.2011
comment
Как использовать встроенные универсальные типы Free Pascal? Google возвращает только темы форума.   -  person mcandre    schedule 18.10.2011
comment
См. ответ monadic на странице Wiki. Кроме того, вы можете обратиться к документации компилятора или к соответствующая глава в справочнике по языку.   -  person    schedule 18.10.2011
comment
Опять же, документы говорят только о том, как создавать общие типы. Я хочу знать, как использовать встроенные универсальные типы Free Pascal в такой функции, как thrice.   -  person mcandre    schedule 18.10.2011


Ответы (3)


Как человек с хаскеллом, который не знает Паскаля, это похоже на то же самое. Извините, что нет возможности расширить.

http://wiki.freepascal.org/Generics

person alternative    schedule 17.10.2011

К сожалению, FreePascal в настоящее время имеет только универсальные классы, а не универсальные функции. Тем не менее, ваша цель все еще может быть достигнута, хотя и немного неуклюже. Вам нужно определить новый класс для инкапсуляции вашей операции:

unit Thrice;

interface

type

generic ThriceCalculator<A> = class
public
  class function Calculate(x: A): array of A;
  // We define it as a class function to avoid having to create an object when 
  // using Calculate. Similar to C++'s static member functions.
end;

implementation

function ThriceCalculator.Calculate(x: A): array of A;
begin
  SetLength(Result, 3);
  Result[0]:= x;
  Result[1]:= x;
  Result[2]:= x;
end;

end.

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

type

  IntegerThrice = specialize ThriceCalculator<Integer>;

Только тогда вы можете использовать его как:

myArray:= IntegerThrice.Calculate(10);

Как видите, Паскаль пока не подходит для обобщенного программирования.

person cyco130    schedule 31.10.2011
comment
Трижды — это только один пример. Придется ли вам создавать специальные классы для FourTimes? FiveTimes? и т.д. - person mcandre; 01.11.2011
comment
Вы можете создать функцию NTimes и взять целочисленный аргумент N. - person cyco130; 01.11.2011
comment
@mcandre: есть примерно два варианта. Создайте один класс для функций, полиморфных по одной переменной без ограничений, и добавьте туда каждую функцию, или создайте класс для каждой функции. Это также возможно комбинировать (например, класс NTimes). В любом случае выбор между ними — это компромисс между беспорядком и простотой расширения. - person ; 01.11.2011
comment
@Тинкториус: Да. +1 за то, что поместил функции в одну и ту же идею универсального класса. - person cyco130; 01.11.2011

...ответ из будущего.

FreePascal поддерживает универсальные функции и процедуры вне классов.

Вот код, который показывает, как вы можете реализовать Thrice как частный случай Times, чтобы также проиллюстрировать ваш вопрос о FourTimes, FiveTimes и т. д.

Код включает в себя пару примеров с использованием разных типов (целое число, строка, запись):

{$mode objfpc}

program Thrice;

uses sysutils;

type
   TPerson = record
      First: String;
      Age: Integer;
   end;

   generic TArray<T> = array of T;

var
   aNumber: integer;
   aWord: String;
   
   thePerson: TPerson;
   aPerson: TPerson;

generic function TimesFn<T, RT>(thing: T; times: Integer): RT;
var i: integer;
begin
   setLength(Result, times);
   for i:= 0 to times-1 do
      Result[i] := thing;      
end;
  
generic function ThriceFn<T, RT>(thing: T): RT;
begin
   Result := specialize TimesFn<T, RT>(thing, 3);
end;


begin
   { Thrice examples }
   
   for aNumber in specialize ThriceFn<Integer, specialize TArray<Integer>>(45) do
                                                  writeln(aNumber);   

   for aWord in specialize ThriceFn<String, specialize TArray<String>>('a word') do
                                                writeln(aWord);

   thePerson.First := 'Adam';
   thePerson.Age := 23;

   for aPerson in specialize ThriceFn<TPerson, specialize TArray<TPerson>>(thePerson) do
                                                   writeln(format('First: %s; Age: %d', [aPerson.First, aPerson.Age]));

   { Times example } 
   for aNumber in specialize TimesFn<Integer, specialize TArray<Integer>>(24, 10) do
                                                 writeln(aNumber);
end.
   
person Joubert Nel    schedule 04.01.2021