I've made a scanner in F#. Currently it returns a list of bunch of tuples with type (Token, string).
Ideally I'd like to return a list of tuples that might contain different types. For example:
(Token, string)
//if it's an identifier
(Token, float)
//if it's a float.
(Token, int)
//etc
So, Basically I'd like to return type (Token, _)
but I'm not sure how to specify this. Right now it just has errors complaining of mismatched types. I'm looking through my bo开发者_StackOverflowok, and wikibooks, but I'm not really sure what this is called.
If this really isn't possible, I guess I can convert the types later on, but I was hoping I could just return stuff this way.
There are two relatively easy ways to handle this in F#. One would be to create a discriminated union:
type Expression =
| Identifier of string
| FloatValue of float
| IntValue of int
| ...
and then define your function so that it returns a (Token * Expression) list
. The other possibility is to box everything into an object and then return a (Token * obj) list
. This is slightly easier for the producer of the list, but much more annoying for the consumer.
I think that using discriminated union as kvb suggests is the way to go. Just to add some more information, when writing scanners in F#, it is common to define a token type Token
that lists various types of tokens that may carry additional information like this:
type Token =
// Some toknes with no additional information
| LParen | RParen | Begin | End
// Some tokens with additional values
| Identifier of string
| IntValue of int
| ...
Then you completely remove the need for representing the value separately from the token and you can work with just Token list
.
As an addition to previous answers, look at the Choice types (and Choice cases such as Choice1of3 etc.).
精彩评论