Free Pascal是否有像Haskell这样的类型变量?

时间:2011-10-17 20:16:53

标签: haskell freepascal type-variables

Haskell允许您定义函数,例如tripice,它接受类型为a的元素,并为任何数据类型a返回重复三次的元素列表。

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

Free Pascal是否允许类型变量?如果没有,还有另一种方法可以在Free Pascal中执行此操作吗?

3 个答案:

答案 0 :(得分:3)

作为一个不熟悉帕斯卡尔的哈斯克尔人,这似乎是一个类似的事情。很抱歉无法扩展。

http://wiki.freepascal.org/Generics

答案 1 :(得分:1)

不幸的是,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);

如你所见,Pascal还不是通用编程的方法。

答案 2 :(得分:0)

...从未来回答。

FreePascal 支持类之外的通用函数和过程。

以下代码展示了如何将三次作为 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.