If we have three different Files with different Derived types,
MyTypeMod.f90:
MODULE MyTypeMod
TYPE, ABSTRACT :: MyType
INTEGER :: Num
END TYPE MyType
CONTAINS
END MODULE MyTypeMod
MyType1Mod.f90
MODULE MyType1Mod
USE MyTypeMod, ONLY : MyType
USE MyType2Mod, ONLY : MyType2
IMPLICIT NONE
TYPE, EXTENDS(MyType) :: MyType1
CONTAINS
PROCEDURE :: Type1EqualsType2
GENERIC :: ASSIGNMENT(=) => Type1EqualsType2
END TYPE MyType1
CONTAINS
SUBROUTINE Type1EqualsType2(Type1, Type2)
TYPE(MyType1), INTENT(OUT) :: Type1
TYPE(MyType2), INTENT(IN) :: Type2
Type1%Num = Type2%Num
END SUBROUTINE Type1EqualsType2
END MODULE MyType1Mod
MyType2Mod.f90
MODULE MyType1Mod
USE MyTypeMod, ONLY : MyType
USE MyType1Mod, ONLY : MyType1
IMPLICIT NONE
TYPE, EXTENDS(MyType) :: MyType2
CONTAINS
PROCEDURE :: Type2EqualsType1
GENERIC :: ASSIGNMENT(=) => Type2EqualsType1
END TYPE MyType2
CONTAINS
SUBROUTINE Type2EqualsType1(Type2, Type1)
TYPE(MyType2), INTENT(OUT) :: Type2
TYPE(MyType1), INTENT(IN) :: Type1
Type2%Num = Type1%Num
END SUBROUTINE Type2EqualsType1
END MODULE MyType2Mod
Here, In this case I couldn't able to compile the Program due to Module files Interdependent on each other. Can I use SubModules to solve the problem?
Unfortunately no, you can't do quite what you want using submodules. This is because both functions
Type1EqualsType2andType2EqualsType1require bothMyType1andMyType2in their function interfaces. Even if you use submodules, both functions will have to have interfaces in their respective modules, and so the circular dependency will remain.However, there are a couple of possible workarounds:
Select type
You can have the
intent(in)arguments of both functions beclass(MyType), and only do type resolution using aselect typestatement. This will allow you to move the function definitions to submodules and resolve the circular dependency, but will also mean that you have to handle cases where a different type which extendsMyTypeis passed to the function. Also,select typecan be a little slow, depending on your use case.Code for this would look something like:
Generic procedure
You can instead replace the type-bound
assignment(=)definitions with genericassignment(=)definitions. This avoids the runtime polymorphism, but means you have to define the assignments in a new module.This would look something like: