Подтвердить что ты не робот

F #: поддержка Nullable <T>

Каков правильный способ использования Nullable в F #?

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

let test (left : Nullable<int>) = if left.HasValue then left.Value else 0

Console.WriteLine(test (new System.Nullable<int>()))
Console.WriteLine(test (new Nullable<int>(100)))

let x = 100
Console.WriteLine(test (new Nullable<int>(x)))
4b9b3361

Ответ 1

Я боюсь, что нет синтаксического сахара для типов с нулевым значением в F # (в отличие от С#, где вы просто добавляете ? к типу). Так что да, код, который вы там показываете, выглядит ужасно многословным, но это единственный способ использовать тип System.Nullable<T> в F #.

Однако я подозреваю, что вы действительно хотите использовать типы опций. На странице MSDN есть несколько достойных примеров:

let keepIfPositive (a : int) = if a > 0 then Some(a) else None

и

open System.IO
let openFile filename =
   try
       let file = File.Open (filename, FileMode.Create)
       Some(file)
   with
       | exc -> eprintf "An exception occurred with message %s" exc.Message; None 

Ясно, что гораздо приятнее использовать!

Параметры, по существу, выполняют роль типов с нулевым значением в F #, и я должен думать, что вы действительно хотите использовать их, а не типы с нулевым значением (если только вы не взаимодействуете с С#). Разница в реализации заключается в том, что типы опций формируются с помощью дискриминированного объединения Some(x) и None, тогда как Nullable<T> является нормальным классом в BCL с небольшим количеством синтаксического сахара в С#.

Ответ 2

Вы можете позволить F # вывести большинство типов:

let test (left : _ Nullable) = if left.HasValue then left.Value else 0

Console.WriteLine(test (Nullable()))
Console.WriteLine(test (Nullable(100)))

let x = 100
Console.WriteLine(test (Nullable(x)))

Вы также можете использовать активный шаблон для применения сопоставления шаблонов для типов с нулевым значением:

let (|Null|Value|) (x: _ Nullable) =
    if x.HasValue then Value x.Value else Null

let test = // this does exactly the same as the 'test' function above
    function
    | Value v -> v
    | _ -> 0

Я некоторое время назад писал о типах с нулевым значением в F # [/shameless_plug]