Я пытаюсь создать функцию, которая преобразует любой числовой тип в float32, а все остальное в 0f.
Сначала я попытался использовать сопоставление по типу, но система типов выводит тип как логический, даже когда я устанавливаю тип как общий.
let numtype x =
match box x with
//| :? sbyte | :? byte | :? int16 | :? int32 | :? int64 | :? uint16 | :? uint32 | :? uint64 | :? nativeint | :? unativeint | :? decimal | :? double | :? float | :? float32 -> float 32 x
| :? char | :? string | :? unit -> 0f
| :? bool -> 0f
| _ -> float32 x
numtype true
Script1.fsx(63,9): ошибка FS0001: ожидалось, что это выражение будет иметь тип «int», но здесь имеет тип «bool»
Затем я попытался использовать перехват ошибок, но он препятствует преобразованию из универсального
let convToNum<'a> (x:'a) =
try
match x with
| :? float32 -> x
with
//| :? System.Exception -> 0f
| _ -> 0f
convToNum 1
Script1.fsx(76,11): ошибка FS0008: это приведение во время выполнения или проверка типа из типа 'a в float32 включает неопределенный тип на основе информации, предшествующей этой программной точке. Тесты типа во время выполнения не разрешены для некоторых типов. Необходимы дополнительные аннотации типов.
У кого-нибудь есть предложение?
обновлено на основе комментариев
@FyodorSoikin Это хороший улов, но он все еще не работает. Ошибка становится Script1.fsx(63,9): ошибка FS0001: ожидалось, что это выражение будет иметь тип «int», но здесь имеет тип «bool»
Это означает, что у вас есть еще одна опечатка, которую вы нам не показываете.
Я думаю, проблема в том, что вы вызываете float32
исходный параметр x
вместо использования приведенного значения. Вместо этого попробуйте что-то вроде этого:
let numtype (x : obj) =
match x with
| :? sbyte as x' -> float32 x'
| :? int16 as x' -> float32 x'
| :? int32 as x' -> float32 x'
| :? int64 as x' -> float32 x'
| :? uint32 as x' -> float32 x'
| :? uint64 as x' -> float32 x'
| :? nativeint as x' -> float32 x'
| :? unativeint as x' -> float32 x'
| :? decimal as x' -> float32 x'
| :? double as x' -> float32 x'
| :? float32 as x' -> x'
| _ -> 0f
Вы также можете использовать встроенный тип System.Convert
:
open System
let numtype (x : obj) =
try Convert.ToSingle(x)
with _ -> 0f
Ваша первая попытка не с, потому что
0
является литераломint
. Вам нужно заменить его на0f
. Или сfloat32 0