On Wednesday, December 30, 2020 at 12:17:35 PM UTC-5, Ev. Drikos wrote:
>.. I don't know very well the (Fortran) language though.
For most Fortranners though, the *safer* approach will be rely on as much *compile-time* assistance and checking as possible, particularly in the case of OP.
They can then define a simple "super object" themselves a la Java and have all their derived types be subclasses thereof i.e., extend from such a base type.
Here's a modified example of your code that I think will work as expected with almost any Fortran compiler out there claiming to support Fortran 2003, 2008 facilities:
--- begin code ---
module base_m
! "super object"
type, abstract :: base_t
contains
private
procedure, pass(lhs) :: IsNotEqual
procedure(Icompare), pass(lhs), deferred, public :: IsEqual
generic, public :: operator(==) => IsEqual
end type base_t
abstract interface
function Icompare( lhs, rhs ) result(r)
import :: base_t
! Argument list
class(base_t), intent(in) :: lhs
class(base_t), intent(in) :: rhs
! Function result
logical :: r
end function
end interface
contains
function IsNotEqual( lhs, rhs ) result(r)
class(base_t), intent(in) :: lhs
class(base_t), intent(in) :: rhs
logical :: r
r = .not.(lhs == rhs)
end function IsNotEqual
end module base_m
module m_type1
use base_m, only : base_t
type, extends(base_t) :: Type1
integer :: n1
contains
procedure :: IsEqual => eq1
end type
contains
function eq1( lhs, rhs) result(r)
class(Type1), intent(in) :: lhs
class(base_t), intent(in) :: rhs
logical :: r
r = .false.
select type ( rhs )
type is ( Type1 )
r = ( lhs%n1 == rhs%n1 )
end select
end function eq1
end module m_type1
module m_type2
use base_m, only : base_t
type, extends(base_t) :: Type2
integer :: n2
contains
procedure :: IsEqual => eq2
end type
contains
function eq2( lhs, rhs) result(r)
class(Type2), intent(in) :: lhs
class(base_t), intent(in) :: rhs
logical :: r
r = .false.
select type ( rhs )
type is ( Type2 )
r = ( lhs%n2 == rhs%n2 )
end select
end function eq2
end module m_type2
program main
use base_m, only : base_t
use m_type1, only: Type1
use m_type2, only: Type2
class(base_t), allocatable :: a, b, c, d
class(base_t), allocatable :: apples, oranges
logical eq
integer :: i=2, j=2
a = Type1( n1 = 100 )
b = Type1( n1 = 100 )
c = Type2( n2 = 200 )
d = Type2( n2 = 200 )
print *, "----------------------------------------------------"
print *, "I'll Compare integers, I thought it should be equal:"
eq = i == j
print *, "MAIN PROGRAM: i == j is:", eq
print *, "I'll Compare Type1 Objects, I thought it should be equal:"
eq = a == b
print *, "MAIN PROGRAM: a == b is:", eq
print *, "I'll Compare Type2 Objects, I thought it should be equal:"
eq = c == d
print *, "MAIN PROGRAM: c == d is:", eq
apples = Type1( n1 = 100 )
oranges = Type2( n2 = 100 )
print *, "I'll Compare Apples & Oranges:"
eq = apples == oranges
print *, "MAIN PROGRAM: apples == oranges is:", eq
end
--- end code ---