Что такое NaN эквивалент для типа int в F#?
В F# я могу разобрать float следующим образом:
let tryParseFloat s =
let ok,f = System.Double.TryParse s
if ok then f else nan
а потом
let parsed = tryParse "123.123"
match parsed with
| nan -> ignore parsed
| _ -> dostuff parsed
Как я могу достичь аналогичной функциональности с Int?
2 ответа
Если вы хотите представить отсутствие значения в F#, используя option
это способ сделать это. Делая это, вы ясно даете понять через систему типов, что значение может или не может быть там. Так что вы обязательно должны использовать int option
Вот.
Я настоятельно советую вам использовать float option
также вместо NaN по той же причине.
Хотя NaN является совершенно допустимым значением для плавающей запятой в.NET, это своего рода вмятина в системе F# -типа. Особенно, nan = nan
Значение false, и оно не очень хорошо подходит для структурных сравнений для сложных типов F# (таких как различимые объединения и записи), которые содержат NaN. Вы получаете ошибки, которые могут быть болезненными, чтобы отследить. Хотя это может быть неизбежно, если вы получаете NaN в результате числовых операций, вы можете сделать это лучше, чем использовать их для представления отсутствия значения.
Так что следуйте советам @FuleSnabel для ints
и использовать что-то подобное для floats
:
let tryParseFloat s =
let ok, f = System.Double.TryParse s
if ok then Some f else None
Изменить: На самом деле, код, который вы опубликовали, не совсем работает, частично из-за вышеизложенного.
match parsed with
| nan -> ignore parsed
| _ -> dostuff parsed
Здесь вы не проверяете NaN, вы связываете parsed
к значению под названием nan
и второй случай никогда не ударится (warning FS0026: This rule will never be matched
).
Немного лучшей попыткой было бы что-то вроде этого:
match parsed with
| f when f = nan -> ignore parsed
| _ -> dostuff parsed
Но здесь первый случай никогда не будет затронут, потому что, как я только что написал выше, f
никогда не будет равным nan
(даже когда parsed
это NaN
)
Вам нужно использовать Double.IsNaN
проверить на NaNs:
match parsed with
| f when System.Double.IsNaN(f) -> ignore parsed
| _ -> dostuff parsed
Но это просто показывает, что это не было хорошей идеей.
tl; dr: NaNs вредны для вас.
int
подобные типы не имеют значения NaN. Вместо этого вы можете использовать int option
, Может быть, что-то вроде этого:
let tryParseInt s =
let ok,i = System.Int32.TryParse s
if ok then Some i else None