Fortran2003では、Array操作がさらに柔軟になっています。ALLOCATABLEな配列を返り値とする関数と、ALLOCATABLE配列の自動再割付が、色々と危険なんですが、便利です。
これらの新機能により、APPENDやCONSのような配列長の変わる操作が簡単に実現できます。
MAPにあたるものは、Fortran95で導入されたELEMENTALな関数で実現できます。(INTRINSICな関数はFortran90からELEMENTALになっていますが)
FILTERにあたるものは、PACK関数によって実現できます。(効率は低そうな気がしますが)
簡単な内包式に当たるものは、配列生成子(array constructor)によって実現できます。
■ソース・コード
gdgdで統一感がないんですが・・
MODULE m_test IMPLICIT NONE CONTAINS FUNCTION iseq(n0, n1, n2) INTEGER, ALLOCATABLE :: iseq(:) INTEGER, INTENT(IN) :: n0, n1 INTEGER, INTENT(IN), OPTIONAL :: n2 INTEGER :: i, istep IF ( PRESENT(n2) ) THEN istep = n2 ELSE istep = 1 END IF iseq = [(i, i = n0, n1, istep)] RETURN END FUNCTION iseq ELEMENTAL INTEGER FUNCTION parity(n) INTEGER, INTENT(IN) :: n parity = MOD(n, 2) RETURN END FUNCTION parity END MODULE m_test !===================================== PROGRAM test USE m_test IMPLICIT NONE INTEGER, ALLOCATABLE :: a(:), b(:), c(:) INTEGER :: i a = [(i, i = -5, 10)] b = PACK(a, a > 4) WRITE(*, '(a, 20i3:)', ADVANCE = 'NO') ' a = -5..10 [', a WRITE(*, '(a)') ' ]' WRITE(*, '(a, 20l3:)', ADVANCE = 'NO') ' a > 4 [', a > 4 WRITE(*, '(a)') ' ]' PRINT * WRITE(*, '(a)') ' filter ' WRITE(*, '(a, 20i3:)', ADVANCE = 'NO') ' b = PACK(a, a > 4) [', b WRITE(*, '(a)') ' ]' PRINT * c = [b, a] ! flatten b = [1, b] ! cons b = [b, [97, 99]] ! append WRITE(*, '(a, (25i3:))', ADVANCE = 'NO') ' b ++ a [', c WRITE(*, '(a)') ' ]' PRINT * WRITE(*, '(a, 20i3:)', ADVANCE = 'NO') ' b = CONS(1, b) ++ [97,99] [', b WRITE(*, '(a)') ' ]' WRITE(*, '(a, 20i3:)', ADVANCE = 'NO') ' MAP parity b [', parity(b) ! MAP WRITE(*, '(a)') ' ]' PRINT * WRITE(*, '(a, 20i3:)', ADVANCE = 'YES') ' CAR b ', b(1) ! CAR WRITE(*, '(a, 20i3:)', ADVANCE = 'NO' ) ' CDR b [', b(2:) ! CDR WRITE(*, '(a)') ' ]' STOP END PROGRAM test