|
| |
| 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){ Two data types are introduced ColoredTree and Hand together
with an example value of each (CT, respectively, H).
The function count is defined at :
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) |