
   MODULE ListModule
    TYPE ListElem
     REAL                    :: value;
     TYPE(ListElem), POINTER :: next;
    END TYPE ListElem
   END MODULE


   SUBROUTINE PrintList(head)
    USE ListModule
    IMPLICIT NONE

    type( ListElem ), pointer :: head
    type( ListElem ), pointer :: ptr

    ptr => head

    print *, "The list is: "
    DO WHILE ( associated(ptr) )
      print *, ptr%value
      ptr => ptr%next
    END DO
    print *
   END SUBROUTINE

! =======================================

   FUNCTION InsertList(head, elem)
    USE ListModule
    IMPLICIT NONE

    type( ListElem ), pointer :: head, elem 
    type( ListElem ), pointer :: InsertList

    elem%next => head 
    InsertList => elem
   END FUNCTION

! =======================================

   FUNCTION DeleteList(head)
    USE ListModule
    IMPLICIT NONE

    type( ListElem ), pointer :: head
    type( ListElem ), pointer :: DeleteList

    type( ListElem ), pointer :: h


    IF ( ASSOCIATED(head) ) THEN
       h => head
       head => head%next
       deallocate(h)
    END IF

    DeleteList => head
   END FUNCTION



! =======================================

   PROGRAM LinkedList
    USE ListModule

    INTERFACE
      SUBROUTINE PrintList(head)
       USE ListModule
       type( ListElem ), pointer :: head
      END SUBROUTINE

      FUNCTION InsertList(head, elem)
       USE ListModule
       type( ListElem ), pointer :: head, elem
       type( ListElem ), pointer :: InsertList
      END FUNCTION

      FUNCTION DeleteList(head)
       USE ListModule
       type( ListElem ), pointer :: head
       type( ListElem ), pointer :: DeleteList
      END FUNCTION
    END INTERFACE

    type( ListElem ), pointer :: head
    type( ListElem ), pointer :: newElem
    integer, parameter :: N = 4

   nullify( head )                 ! Initialize list to point to no target.

! ---------------------------------------------
! Add the N elements
! ---------------------------------------------
   DO i = 1, N
      allocate( newElem )

      CALL random_number( newElem%value )

      head => InsertList(head, newElem)
      CALL PrintList(head)
   END DO

   print *, ""
   print *, "Deleting from list...."

   head => DeleteList(head)
   CALL PrintList(head)

   end program LinkedList

