Question

I don't know, if this is called currying, but I want to have a HashMap(String, Long, Short, String);

The GNAT compiler complains:

main.adb:20:13: warning: possible infinite recursion
main.adb:20:13: warning: Storage_Error may be raised at run time
main.adb:24:13: warning: possible infinite recursion
main.adb:24:13: warning: Storage_Error may be raised at run time

What is the correct way to write the "=" function here?

main.adb

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ada.Text_IO;

procedure Main is
   subtype Short is Short_Integer;
   subtype Long is Long_Integer;

   function Hash (X : String) return Ada.Containers.Hash_Type is
      (Ada.Strings.Hash (X));

   function Hash (X : Short) return Ada.Containers.Hash_Type is
      (Ada.Containers.Hash_Type'Mod (X));

   function Hash (X : Long) return Ada.Containers.Hash_Type is
      (Ada.Containers.Hash_Type'Mod (X));

   package Short_String_Map is new Ada.Containers.Indefinite_Hashed_Maps (Short, String, Hash, "=");
   function "=" (Left, Right : Short_String_Map.Map) return Boolean is
      (Left = Right);

   package Long_Short_Map is new Ada.Containers.Indefinite_Hashed_Maps (Long, Short_String_Map.Map, Hash, "=");
   function "=" (Left, Right : Long_Short_Map.Map) return Boolean is
      (Left = Right);

   package String_Long_Map is new Ada.Containers.Indefinite_Hashed_Maps (String, Long_Short_Map.Map, Hash, "=");
begin
   --  Map(String, Long, Short, String);
   null;
end Main;
Was it helpful?

Solution

Instead of

function "=" (Left, Right : Short_String_Map.Map) return Boolean is
    (Left = Right);

write

function "=" (Left, Right : Short_String_Map.Map) return Boolean is
    (Short_String_Map."=" (Left, Right));

or, even better (I think):

function "=" (Left, Right : Short_String_Map.Map) return Boolean 
    renames Short_String_Map."=";     

The problem is that the way you wrote it, the = in Left = Right refers to the "=" that you just defined on the line above, according to the visibility rules. Naturally this means you've just defined an infinitely recursive function. To use the "=" defined in Short_String_Map instead, you have to use a syntax like Short_String_Map."="(Left,Right) to make it explicit which "=" you're referring to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top