You should specify the access-to-subprogram type you need as your formal parameter.
Ada Language Reference Manual section 12.5.4 states: "For a formal access-to-subprogram subtype, the designated profiles of the formal and the actual shall be subtype conformant."
This leads to declaring something like the following:
generic
type func_type is access function(S : String) return string;
gen_func : not null func_type;
type proc_type is access procedure (Msg : in String);
gen_proc : not null proc_type;
package test_subprog is
procedure Print;
end test_subprog;
You must declare both the access to subprogram type and a formal parameter for the corresponding access to subprogram instance. If you specify that the formal parameter must be "not null" then you need not test for a null parameter in your code.
with Ada.Text_IO; use Ada.Text_IO;
package body test_subprog is
-----------
-- Print --
-----------
procedure Print is
Msg : string := "This is a test";
begin
Put_Line(Item => gen_func(Msg));
gen_proc(gen_func(Msg));
end Print;
end test_subprog;
Calling the formal access to subprograms passed as generic parameters takes no special syntax. Making an instance of the actual parameters to use the generic package can be done as:
with Ada.text_io; use Ada.Text_IO;
with test_subprog;
procedure Main is
function format(S : String) return String is
begin
return "Called through function access " & S;
end format;
type format_access is access function(S : string) return String;
procedure reformat(S : String) is
begin
Put_Line("Called through procedure access " & S);
end reformat;
type proc_access is access procedure (S : String);
package sub_test is new test_subprog(func_type => format_access,
gen_func => format'access,
proc_type => proc_access,
gen_proc => reformat'access);
begin
sub_test.print;
end Main;
This convoluted approach allows you to use access to subprogram types as generic parameters. Unless you actually need an access to subprogram type one can simply use a subprogram formal parameter such as is described in the Ada Language Reference Manual section 12.6:
Examples of generic formal subprograms:
with function "+"(X, Y : Item) return Item is <>;
with function Image(X : Enum) return String is Enum'Image;
with procedure Update is Default_Update;
with procedure Pre_Action(X : in Item) is null; -- defaults to no action
with procedure Write(S : not null access Root_Stream_Type'Class;
Desc : Descriptor)
is abstract Descriptor'Write; -- see 13.13.2
-- Dispatching operation on Descriptor with default
-- given the generic procedure declaration
generic
with procedure Action (X : in Item);
procedure Iterate(Seq : in Item_Sequence);
-- and the procedure
procedure Put_Item(X : in Item);
-- the following instantiation is possible
procedure Put_List is new Iterate(Action => Put_Item);