3
votes

I was wondering if it is somehow possible to define a derived type in Fortran which automatically returns the right type, without calling the type specifically e.g. var%real? Here's an example to explain what I mean:

module DervType

  implicit none

  type, public :: mytype
    real(8) :: r
    integer :: i
    logical :: l
  end type

end module DervType

program TestType

  use DervType

  implicit none

  type(mytype) :: test

  test = 1.                   !! <-- I don't want to use test%r here

end program TestType

Would this be possible by defining some sort of interface assignment (overload the =) or something like that? Is this even possible?

Thanks! Any help appreciated!

1
Yes, it is possible to have defined assignment. Can you try that to see whether it does what you want? I guess this is related to your previous question, but you can do this without the polymorphism. - francescalus
But this is a very specific aspect of your question. That is, test = x can be done so that the component of test set is in some way determined by the type of x. However, is this what you mean? The part "which automatically returns the right type" suggests you may need to do something more exotic (like call sub(test) acts like call sub(test%r) if the argument is real, etc.). - francescalus
Thanks for the answer! Yes, I guess this is all related even though I gave up on the other stuff... If I compile the above I get: Error: Can't convert REAL(4) to TYPE(mytype), so this does not work. Sorry, I've looked at the example from your link but I don't understand it. I do need an interface right? - Florian Ragossnig
So I'll have to define a couple of functions (real, int, logic) and assign them through the interface? Gonna try that! Thanks! - Florian Ragossnig

1 Answers

3
votes

Found a solution to this and it was actually quite simple. Here's the code:

module DervType

  implicit none

  type, public :: mytype
    real(8)                       :: r
    integer                       :: i
    character(len=:), allocatable :: c
    logical :: l
  end type

  interface assignment(=)                 // overload = 
    module procedure equal_func_class
  end interface

contains

  subroutine equal_func_class(a,b)

    implicit none

    type(mytype), intent(out) :: a
    class(*), intent(in)      :: b

    select type (b)
        type is (real)
            print *, "is real"
            a%r = b
        type is (integer)
            print *, "is int"
            a%i = b
        type is (character(len=*))
            print *, "is char"
            a%c = b
        type is (logical)
            print *, "is logical"
            a%l = b 
    end select

    return

  end subroutine equal_func_class  

end module DervType

program TestType

  use DervType

  implicit none

  type(mytype) :: test

  test = 1.      // assign real 
  test = 1       // assign integer
  test = "Hey"   // assign character
  test = .true.  // assign logical

  print *, "Value (real)      : ", test%r
  print *, "Value (integer)   : ", test%i
  print *, "Value (character) : ", test%c
  print *, "Value (logical)   : ", test%l

end program TestType

I'm trying to use the variables within a program now (e.g. do some arithmetic calculations, etc.) but that seems to be rather difficult if not impossible. I might start another question about that.