module a
  implicit none
  private

  type, public :: typ
    integer :: i
    real    :: a
  end type

  public :: operator(+)
  public :: assignment(=)

  interface operator(+)
    module procedure add
  end interface

  interface assignment(=)
    module procedure assign
  end interface

contains
!==============================================================
!
!==============================================================
function add(x, y) result(z)
  implicit none
  type(typ), intent(in) :: x, y
  type(typ)             :: z

  z%i = x%i + y%i
  z%a = x%a + y%a
end function add
!==============================================================
!
!==============================================================
subroutine assign(x, y)
  implicit none
  type(typ), intent(out) :: x
  type(typ), intent(in)  :: y

  x%i = y%i
  x%a = y%a
end subroutine assign
!==============================================================
!
!==============================================================
end module a
!==============================================================
!
!==============================================================
program main
  use a, only: typ, operator(+), assignment(=)
  implicit none
  type(typ) :: x, y, z

  x%i = 1
  x%a = 1.5

  y%i = 2
  y%a = 0.3

  z = x + y
  print*, 'z%i:',z%i,', %a:',z%a

  y = x
  print*, 'y%i:',y%i,', %a:',y%a
end program main