You can basically do that (as also mentioned in Vladimir's answer) with defining functor objects. They have one specific function returning the value (e.g. getvalue()
), and depending on their initialization, they may return customized function values.
The example below demonstrates that in detail. The general functor is defined in functor_module
, in expfunc_module
a concrete realization for the exponential function family is derived. Then, in the main program then you initialize different instances with different prefactors in the exponents and can use their getvalue()
method to obtain the appropriate function values.:
module functor_module
implicit none
integer, parameter :: wp = kind(1.0d0)
type, abstract :: functor
contains
procedure(getvalue_iface), deferred :: getvalue
end type functor
interface
function getvalue_iface(self, xx) result(yy)
import
class(functor), intent(in) :: self
real(wp), intent(in) :: xx
real(wp) :: yy
end function getvalue_iface
end interface
end module functor_module
module expfunc_module
use functor_module
implicit none
type, extends(functor) :: expfunc
real(wp) :: aa
contains
procedure :: getvalue
end type expfunc
contains
function getvalue(self, xx) result(yy)
class(expfunc), intent(in) :: self
real(wp), intent(in) :: xx
real(wp) :: yy
yy = exp(self%aa * xx)
end function getvalue
end module expfunc_module
program test_functors
use expfunc_module
implicit none
type(expfunc) :: func1, func2
real(wp) :: xx
func1 = expfunc(1.0_wp)
func2 = expfunc(2.0_wp)
xx = 1.0_wp
print *, func1%getvalue(xx) ! gives exp(1.0 * xx) = 2.718...
print *, func2%getvalue(xx) ! gives exp(2.0 * xx) = 7.389...
end program test_functors