I’ve been implementing an enhanced Shunting-Yard algorithm for parsing an arithmetic expression. One aspect of the algorithm, is that it maintains a Queue, and a Stack.
In my implementation, the Queue contains Expressions and Operators.
The Stack contains Operators and Parenthesis.
Expressions, Parenthesis, and Operators have nothing in common that warrants any two of them having a shared interface.
Approaches:
-
My current implementation consists of
ExpressionandOperatorimplementing aINotParanthesis.OperatorandParanthesisimplement aINotExpression. I then declareQueue <INotParanthesis>, andStack <INotExpression>.I don’t like this implementation – these interfaces seem very much a hack for the purpose of cleaner algorithm code. I also believe that interfaces should describe what an object is, as opposed to what it isn’t.
-
On the other hand, I also don’t want to use collections of
<Object>, as it can be difficult to be certain of the correctness of such code. -
The only one I’ve come up with, so far, is implementing my own
NonParanthesisQueueandNonExpressionStackcontainers. This has the advantage of more consistent type checking on objects getting pulled out of those containers – and the disadvantage of a lot more code.
Are there any reasonable alternatives to my approaches?
It sounds like what you really want is a sum type. Although C# does not have these built in, there’s a trick from functional programming that you can use called Church encoding to achieve this. It’s completely type safe with no casts involved, however it’s a bit weird to use in C# mostly due to the limitations of the type inference.
The main trick is that instead of using properties and checks to retrieve one of the two alternatives, we have a higher order function
Mapthat takes two functions as arguments and calls the appropriate one depending on which alternative was present. Here’s how you would use it:Here’s the implementation of
IEither,LeftandRight. They are fully generic and could be used anywhere you want a sum type.References: