Navigation Synopsis Generic function that can count constructors in a value of any algebraic data type. Description In ColoredTrees, we have seen a function that can count the number of red nodes in a `ColoredTree`. Is it possible to define a function that can count constructors in a value of any algerbaic data type? We exploit the subtype relation (see Rascal:StaticTyping) between Rascal:AlgebraicDataTypes and the type Rascal:Node to achieve this. In real applications this becomes relevant when counting, for instance, statement types in programs. Examples ```module demo::common::CountConstructors import Node; import Map; // Define a ColoredTree data type data ColoredTree = leaf(int N) | red(ColoredTree left, ColoredTree right) | black(ColoredTree left, ColoredTree right); public ColoredTree CT = red(black(leaf(1), red(leaf(2),leaf(3))), black(leaf(3), leaf(4))); // Define a Card data type. data Suite = hearts() | diamonds() | clubs() | spades(); data Card = two(Suite s) | three(Suite s) | four(Suite s) | five(Suite s) | six(Suite s) | seven(Suite s) | eight(Suite s) | nine(Suite s) | ten(Suite s) | jack(Suite s) | queen(Suite s) | king(Suite s) | ace(Suite s); data Hand = hand(list[Card] cards); public Hand H = hand([two(hearts()), jack(diamonds()), six(hearts()), ace(spades())]); // Count frequencies of constructors public map[str,int] count(node N){ freq = (); visit(N){ case node M: { name = getName(M); freq[name] ? 0 += 1; } } return freq; } public map[str,int] countRelevant(node N, set[str] relevant) = domainR(count(N), relevant); ``` Two data types are introduced `ColoredTree` and `Hand` together with an example value of each (`CT`, respectively, `H`). The function `count` is defined at : introduces an empty map to maintain the frequencies. defines a visit of argument `N`; it traverses the complete value of `N`. defines the case that we encounter a node and we update its frequency count. First the name of the constructor is retrieved (using Rascal:getName) and then the frequency is updated. The Rascal:IsDefined operator is used to provide a default value of 0 when the name was not yet in the map. the map `freq` is returned as result. A variant `countRelevant` is defined at ; it gets is an extra argument of relevant constructors names that is used to filter the map that is returned by `count` using Rascal:domainR. ```rascal>import demo::common::CountConstructors; ok rascal>count(CT); map[str, int]: ("red":2,"leaf":5,"black":2) rascal>count(H); map[str, int]: ("six":1,"ace":1,"two":1,"hearts":2,"spades":1,"hand":1,"diamonds":1,"jack":1) rascal>countRelevant(H, {"hearts", "spades"}); map[str, int]: ("hearts":2,"spades":1) ```  | [New Subconcept] | [Recompile Course] | [Warnings] Is this page unclear, or have you spotted an error? Please add a comment below and help us to improve it. For all other questions and remarks, visit ask.rascal-mpl.org.