Общее правило для разрешения конфликтов имен в F # - «последнее объявление». Поскольку ваш пользовательский DU объявлен после Option
, его конструкторы Some
и None
выигрывают от своих Option
.
Но это правило предлагает способ исправить проблему: вам просто нужно «reassert» декларации после вашего пользовательского DU:
type Bogus = Some of int | None
let g = function Some _ -> 42 | None -> 5
let x = Some 42
let inline Some a = Option.Some a
let inline None<'a> = Option.None : 'a option
let (|Some|None|) = function | Option.Some a -> Some a | Option.None -> None
let f = function Some _ -> 42 | None -> 5
let y = Some 42
Если вы проверяете типы g
, x
, f
и y
в приведенном выше коде:
> g
g : Bogus -> int
> f
f : 'a option -> int
> x
Bogus
> y
int option
Предполагалось, что функция g
и значение x
имеют тип Bogus -> int
и Bogus
соответственно, поскольку Some
и None
в их телах относятся к Bogus.Some
и Bogus.None
.
Вычислены функции f
и значение y
, имеющие Option
-связанные типы, поскольку Some
и None
в их телах относятся к функции Some
и (|Some|None|)
активный шаблон, который я определил чуть выше.
Конечно, это довольно хакерский способ восстановить статус-кво. Это убедит компилятор, но людям все равно придется читать код. Я предлагаю вам переименовать случаи вашего DU.