iterate over the elements of a module - Maple Help

Online Help

All Products    Maple    MapleSim


Home : Support : Online Help : Programming : Modules : Module Exports : ModuleIterator

ModuleIterator - iterate over the elements of a module

Calling Sequence

module() local ModuleIterator, ...; ... end module;

module() option object; export lowerbound, upperbound, `?[]`, ...; ...; end module;

Description

• 

The ModuleIterator routine allows a module or object to return an interface that can be used to iterate over elements contained within the module (or object).

• 

If a module defines a ModuleIterator routine as a local or export, that module may be used as the container in for-in loops, as well as calls to seq, add and mul.

• 

A call to ModuleIterator should return two procedures.

(hasNext,getNext) := ModuleIterator( obj );

 

The hasNext function should return true or false depending on if there are more elements remaining.

The getNext function should return the next element to be accessed.

• 

The basic pattern for using these routines is as follows

while hasNext() do
      e := getNext();
      # Do something with e.
  end do;

• 

It should always be safe to call getNext if a call to hasNext returns true.  If a call to hasNext returns false, the return value of a call to getNext is unspecified.

• 

Calling hasNext multiple times without intervening calls to getNext should always return the same result.

• 

If the module being defined is an object, then there is an alternative mechanism for iterating over the module. This works by overriding three methods for the object: lowerbound, upperbound, and `?[]`. If an object has these three methods but no ModuleIterator member, then Maple will call the lowerbound and upperbound members to get bounds (which must be integers) for indexing, and the `?[]` member to retrieve the elements between these bounds, inclusive. In particular, for such an object m,

for e in m do
      # Do something with e.
  end do;

  

is equivalent to

for i from lowerbound(m) to upperbound(m) do
      e := m[i];
      # Do something with e.
  end do;

Examples

We can create a module that can be used to iterate over all prime numbers.

Primes := module()
   local ModuleIterator := proc()
       local i;

       i := 1;

       (
           proc()
               true;
           end proc,
           proc()
               i := nextprime( i );
           end proc
       )
   end proc;
end module;

Primes:=modulelocalModuleIterator;end module

(1)

As there are infinitely many primes, we need to introduce our own termination condition.

foriinPrimesdoif100<ithenbreakend if&semi;printiend do

2

3

5

7

11

13

17

19

23

29

31

37

41

43

47

53

59

61

67

71

73

79

83

89

97

(2)

A container object with a ModuleIterator can be used like a built-in Maple structure.

module IterObj()
   option object;

   local _list;

   export setValue::static := proc( obj::IterObj, l::list )
       obj:-_list := l
   end proc;

   export ModuleIterator::static := proc( obj::IterObj )
       local i, l;

       i := 1;
       l := obj:-_list;

       (
           proc()
               i <= numelems( l )
           end proc,
           proc()
               local e;
               e := l[i];
               i := i+1;
               e;
           end proc
       );
   end proc;
end module:

io:=ObjectIterObj&colon;

setValueio&comma;1&comma;2&comma;3&colon;

hasNext&comma;getNext:=ModuleIteratorio

hasNext&comma;getNext:=proci<=numelemslend proc&comma;proclocale&semi;e:=l&lsqb;i&rsqb;&semi;i:=i&plus;1&semi;eend proc

(3)

whilehasNextdoe:=getNextend do

1

2

3

(4)

foriiniodoiend do

1

2

3

(5)

addi&comma;i&in;io

6

(6)

muli&comma;i&in;io

6

(7)

seqi2&comma;i&in;io

1&comma;4&comma;9

(8)

Alternatively, this object could be implemented as follows.

module IterObj2()
   option object;

   local _list;

   export setValue::static := proc( obj::IterObj2, l::list )
       obj:-_list := l
   end proc;

   export lowerbound::static := ( self::IterObj2 ) -> 1;
   export upperbound::static := ( self::IterObj2 ) -> numelems( self:-_list );

   export `?[]`::static := proc( self::IterObj2, idx::list )
       if type( idx, ['posint'] ) and idx[1] <= numelems( self:-_list ) then
           return self:-_list[idx[1]];
       else
           error "invalid subscript selector";
       end if;
   end proc;
end module:

io2:=ObjectIterObj2&colon;

setValueio2&comma;1&comma;2&comma;3&colon;

foriinio2doiend do

1

2

3

(9)

addi&comma;i&in;io2

6

(10)

muli&comma;i&in;io2

6

(11)

seqi2&comma;i&in;io2

1&comma;4&comma;9

(12)

See Also

add, for, module, mul, Object, Object,create, Object,methods, Object,overview, procedure, seq


Download Help Document

Was this information helpful?



Please add your Comment (Optional)
E-mail Address (Optional)
What is ? This question helps us to combat spam