F # Avoid overwriting the active structure
I noticed that I cannot create two active templates with the same parameters, but I can have two with similar ones without warning:
let (|A|B|C|) c =
if (c = 'a') then A
else if (c = 'b') then B
else C
let (|A|B|D|) c =
if (c = '1') then A
else if (c = '2') then B
else D
So, if you follow this path:
let check myvar =
match myvar with
| A -> printf "match A\n"
| n -> printf "match other %A\n" n
It happens:
check 'x' // match other 'x'
check 'a' // match other 'a' !!
check '1' // match A
I'm a little concerned about unintentionally overwriting existing active template options, for example in situations where the same word might appear in different templates because of different semantic contexts like (|Direct|Indirect|)
(route) and (|Alternating|Direct|)
(current).
How can I avoid such situations?
source to share
I agree that shadowing active templates can be tricky - although this is the same problem that you face with discriminated cases of merging and writing shortcuts in F #. In the case of types, you can always specify the type name to eliminate ambiguity.
In the case of active templates, you can put them in modules - for example Pat1
and Pat2
:
module Pat1 =
let (|A|B|C|) c =
if (c = 'a') then A
else if (c = 'b') then B
else C
module Pat2 =
let (|A|B|D|) c =
if (c = '1') then A
else if (c = '2') then B
else D
So, in your code, you can use the fully qualified name, for example, Pat1.A
or Pat2.A
:
let check myvar =
match myvar with
| Pat1.A -> printf "match A\n"
| n -> printf "match other %A\n" n
source to share
I think your concerns relate to shading in general, not just active templates. How often do you define two active templates whose parameters and return values ββare the same and have the same name names? Typically, types mitigate potential shading problems. Along these lines, enter annotations - your friend.
source to share