AdaでCurry化

Curry化もできない奴とは話をしたくないと言われたので、がんばってみた。

ふぁーすとらい。関数ポインタ編。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Curry is

   -- Ada95で追加された副プログラムへのアクセス型を使ってみる
   type Sum_Function_Type is access function(Y : in Integer) return Integer;
   function Curried_Sum(X : in Integer) return Sum_Function_Type is
      C : Integer;
      function Sum(Y : Integer) return Integer is
      begin
         return C + Y;
      end Sum;
   begin
      C := X;
      return Sum'Access;
   end Curried_Sum;

   Z : Sum_Function_Type;
begin
   Z := Curried_Sum(10);
end Curry;
curry.adb:15:14: subprogram must not be deeper than access type

いけると思ったのになー。これ、Ada05でも駄目かな?

せかんどとらい。Taskは世界を救う編。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Curry is
   task type Sum_Task is
      entry Set_X(X : in Integer);
      -- なんで返値渡せるentryって存在しないんだろ
      entry Calc(Y : in Integer; Result : out Integer);
   end Sum_Task;

   task body Sum_Task is
      C : Integer; -- Xを保存しておくところ
   begin
      accept Set_X(X : in Integer) do
         C := X; 
      end Set_X;

      -- ループして何回でも使えるようにしておく
      loop
         select
            accept Calc(Y : in Integer; Result : out Integer) do
               Result := C + Y;
            end Calc;
         or
            terminate;
         end select;
      end loop;
   end Sum_Task;

   type Sum is access Sum_Task;

   function Curried_Sum(X : in Integer) return Sum is
      S : Sum;
   begin
      S := new Sum_Task;
      S.Set_X(X);
      return S;
   end Curried_Sum;

   S : Sum;
   R : Integer;

begin
   S := Curried_Sum(10);
   S.Calc(10, R);
   Put(R); -- 20
   S.Calc(20, R);
   Put(R); -- 30

   -- ドットで繋いでも書けるぞ!
   Curried_Sum(5).Calc(10, R);
   Put(R); -- 15
end Curry;

おおー、なんかちょっとカリー化とは違う気がするけど、おおむねね期待通りだ! なんかもう必死すぎて涙が出てきますね。え、任意の関数で出来るようにしろって?

もっと簡単にかける気がするので、誰かトライお願いします。