Free Pascal 有像 Haskell 那样的类型变量吗?

发布于 2024-12-10 13:22:55 字数 230 浏览 0 评论 0原文

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

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

Free Pascal 允许类型变量吗?如果没有,在 Free Pascal 中还有其他方法可以做到这一点吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

痕至 2024-12-17 13:22:55

作为一个不了解 Pascal 的 haskell 人,这似乎是类似的事情。抱歉无法扩展。

http://wiki.freepascal.org/Generics

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

非要怀念 2024-12-17 13:22:55

不幸的是 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 还不是泛型编程的最佳选择。

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.

淤浪 2024-12-17 13:22:55

……来自未来的回答。

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.
   

...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.
   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文