I am not an Ada expert, but I came up with this. Please notice that the idea here is not to have the compiler do proper dimensional analysis but simply to avoid the default operator overloading of "*" for the Distance type that also returns a Distance value.
Nothing very high-level, as we need to explicitly manipulate the single-component records, but it does the job.
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Distance is record
Value : Float;
end record;
type Area is record
Value : Float;
end record;
function "*" (Left, Right : Distance) return Area is
begin
return (Value => Left.Value * Right.Value);
end "*";
D1 : constant Distance := (Value => 10.0);
D2 : constant Distance := (Value => 20.0);
-- D3 : constant Distance := D1 * D2;
-- Does not compile. GNAT returns the following error:
-- main.adb:21:33: expected type "Distance" defined at line 4
-- main.adb:21:33: found type "Area" defined at line 8
A : constant Area := D1 * D2;
begin
Put_Line ("Area A is " & Float'Image(A.Value));
end Main;*