Sorry for a naïve question. For example, if I want to define a function func(x), its behavior depends on the type of the input x. I mean I can use module procedure to define several functions, then overload them to func. However, is it possible to do such things more easily? like
function func(x)
real :: func
if (  x is real  .or. x is complex  .or. x is integer) then 
do something 
end if
So that I do not need to write several do something functions which are the same actually, and then overload them to func?
PS.
The real two functions are my scattervi1d and scattervr1d which are mpi_scatterv wrapper as shown below, one deal with integer array scatterv, the other deal with real array scatterv. I overload them to scatterv. However the content of the scattervi1d and scattervr1d are almost exactly the same. The only difference is just type of the input variables r,rscatter (scattervi1d deals with integer input, scattervr1d deals with real input). I feel it is a little bit redundant to define basically the same functions twice.
interface scatterv ! scatterv from process 0 to all process, evenly scatter. inverse of gather
  module procedure scattervi1d   
  module procedure scattervr1d
end interface scatterv
! https://stackoverflow.com/questions/17508647/sending-2d-arrays-in-fortran-with-mpi-gather/17530368#17530368   
   subroutine scattervi1d(r,rscatter,scounts,displs)
   integer(kind=i4) :: r(:),rscatter(:)
   integer :: i,ierror,scounts_default(iproc),displs_default(iproc) 
   integer, optional :: scounts(iproc),displs(iproc) 
   if (.not.(present(scounts).and.present(displs))) then ! here assume no scounts and no displs.     
     call gather(size(rscatter),scounts_default)
     if (myrank()==0) then
       displs_default(1)=0
       do i=2,iproc
         displs_default(i)=displs_default(i-1)+scounts_default(i-1)
       enddo
     endif    
     call mpi_scatterv(r,scounts_default,displs_default,mpir8,rscatter,size(rscatter),mpir8,0, &
                       mpi_comm_world,ierror)
   else
     call mpi_scatterv(r,scounts,displs,mpir8,rscatter,size(rscatter),mpir8,0, &
                       mpi_comm_world,ierror)     
   endif
   return
   end subroutine scattervi1d  
   
   
   subroutine scattervr1d(r,rscatter,scounts,displs)  
   real(kind=r8) :: r(:),rscatter(:)
   integer :: i,ierror,scounts_default(iproc),displs_default(iproc) 
   integer, optional :: scounts(iproc),displs(iproc) 
   if (.not.(present(scounts).and.present(displs))) then ! here assume no scounts and no displs.     
     call gather(size(rscatter),scounts_default)
     if (myrank()==0) then
       displs_default(1)=0
       do i=2,iproc
         displs_default(i)=displs_default(i-1)+scounts_default(i-1)
       enddo
     endif    
     call mpi_scatterv(r,scounts_default,displs_default,mpir8,rscatter,size(rscatter),mpir8,0, &
                       mpi_comm_world,ierror)
   else
     call mpi_scatterv(r,scounts,displs,mpir8,rscatter,size(rscatter),mpir8,0, &
                       mpi_comm_world,ierror)     
   endif
   return
   end subroutine scattervr1d