3

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!

8
  • 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. Commented Sep 26, 2018 at 11:01
  • See also: this question. Commented Sep 26, 2018 at 11:05
  • 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.). Commented Sep 26, 2018 at 11:17
  • 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? Commented Sep 26, 2018 at 11:17
  • 1
    So I'll have to define a couple of functions (real, int, logic) and assign them through the interface? Gonna try that! Thanks! Commented Sep 26, 2018 at 11:25

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

This is a bad idea. When someone references test you have no way of knowing which value they want - the real, integer, logical or character. So your assignment looks different from your value access, which is confusing.
Well, I guess this depends on how you would like to use it. At the moment I agree that this is the case but that was not part of this question. I simply wanted to find out how or if it is possible to assign a value to a deferred type without knowing the input type. At the moment I'm working on the other way round.
Actually, the solution with many procedures inside an interface has the advantage that if you try to assign a type that is not covered, you get a compile-time error. Otoh, using a class(*) with a select type, the best you could have is a run-time error (consider using a select default clause)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.