Как я могу иметь функцию, которая возвращает различные типы в F#?

Я сделал сканер в F#. В настоящее время он возвращает список групп кортежей с типом (Token, string).

В идеале я хотел бы вернуть список кортежей, которые могут содержать разные типы. Например:

(Token, string) 
//if it's an identifier

(Token, float)
//if it's a float. 

(Token, int)
//etc

Итак, в основном я хотел бы вернуть тип (Token, _) но я не уверен, как это указать. Прямо сейчас это просто ошибки, жалующиеся на несовпадающие типы. Я просматриваю свою книгу и вики-книги, но я не совсем уверен, как это называется.

Если это действительно невозможно, я думаю, что смогу позже преобразовать типы, но я надеялся, что смогу просто так вернуть вещи.

3 ответа

Решение

Есть два относительно простых способа справиться с этим в F#. Можно было бы создать дискриминационный союз:

type Expression =
| Identifier of string
| FloatValue of float
| IntValue of int
| ...

а затем определите свою функцию так, чтобы она возвращала (Token * Expression) list, Другая возможность состоит в том, чтобы поместить все в объект и затем вернуть (Token * obj) list, Это немного проще для производителя списка, но намного раздражает для потребителя.

Я думаю, что использование дискриминационного союза, как подсказывает kvb, - это путь. Чтобы добавить больше информации, при написании сканеров на F# обычно определяют тип токена. Token это перечисляет различные типы токенов, которые могут нести дополнительную информацию как это:

type Token = 
// Some toknes with no additional information
| LParen | RParen | Begin | End
// Some tokens with additional values
| Identifier of string
| IntValue of int
| ...

Затем вы полностью избавляетесь от необходимости представлять значение отдельно от токена, и вы можете работать только с Token list,

В дополнение к предыдущим ответам, посмотрите на типы выбора (и варианты выбора, такие как Choice1of3 и т. Д.).

Другие вопросы по тегам