Problems with polymorphic transfer functions on the left of an arrow
using RankNTypes:
- Can't easily write generic debugging code to show facts
propagating through a graph, because
. can't tell the shape of the node
. therefore can't tell the type of the facts
- Can't write a generic dominator analysis that assumes only (Edges n)
- Can't use default cases (or at least not easily) in the transfer
function
- Harder to reuse common predicate transformers like
- id
- distributeFacts :: Edges n => n -> f -> FactBase f
distributeFacts n f = mkFactBase [(l, f) | l <- successors n]
----------------------------------
Instructions given to NR's class:
All,
If you consult the type definition of FwdTransfer,
you'll see that it requires a polymorphic function and uses a type
family which alters the types of arguments and results depending on
the shape of a node. If the type of a fact is 'f', then
- The predicate transformer for a closed/open node has type f -> FactBase f
- The predicate transformer for an open/open node has type f -> f
- The predicate transformer for an open/closed node has type FactBase f -> f
Simon was very enamored of this interface, but it's clear that it
imposes a heavy burden on clients:
1. For a typical first node such as
LabelNode l
You'll have to capture the fact using
fromJust $ factLookup factbase l
2. For a last node you may want something like
\f -> mkFactBase [(l, f) | l <- successors n]
Some last nodes may require more elaborate code.
3. Because the function is both GADT and polymorphic, you can't
default any cases---every constructor has to be written
explicitly. When you are doing this, but you don't care about the
constructor's arguments, it can be useful to use the record
wildcard syntax:
xfer (ArraySet {}) = id
This syntax matches any fully saturated application of ArraySet,
no matter how many arguments ArraySet expects.
Norman