mcandre
mcandre

Reputation: 24602

Does Free Pascal have type variables like Haskell?

Haskell lets you define functions like thrice, which accepts an element of type a and returns a list of the element repeated three times, for any data type a.

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

Does Free Pascal allow type variables? If not, is there another way to do this in Free Pascal?

Upvotes: 4

Views: 667

Answers (3)

Joubert Nel
Joubert Nel

Reputation: 3214

...answering from the future.

FreePascal has support for generic functions and procedures outside of classes.

Here's code that shows how you could implement Thrice as a special case of Times to also illustrate your ask about "FourTimes, FiveTimes, etc.".

The code includes a couple of examples using different types (integer, string, record):

{$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.
   

Upvotes: 0

cyco130
cyco130

Reputation: 4934

Unfortunately FreePascal currently has only generic classes, not generic functions. Though, your goal can still be achieved, albeit a little awkwardly. You need to define a new class to encapsulate your operation:

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.

Now, unfortunately when you want to use this class with any specific type, you need to specialize it:

type

  IntegerThrice = specialize ThriceCalculator<Integer>;

Only then you can use it as:

myArray:= IntegerThrice.Calculate(10);

As you see, Pascal is not the way to go for generic programming yet.

Upvotes: 1

alternative
alternative

Reputation: 13012

As a haskell person who doesn't know Pascal, this appears to be a similar thing. Sorry for not being able to expand.

http://wiki.freepascal.org/Generics

Upvotes: 3

Related Questions