F # Неявный ModuleSuffix не работает при использовании полностью определенного имени - PullRequest
3 голосов
/ 29 января 2020

У меня есть проект F # с файлом, который определяет тип и модуль следующим образом:

module Domain 
  type TodoID = TodoID of int
  module TodoID = let value (TodoID i) = i

  let ti = TodoID 1
  let i1 = TodoID.value ti // Works as expected

Компилятор F # автоматически добавляет суффикс "Module" к TodoID, так что полное имя распаковываемого имени функция Domain.TodoIDModule.value, как и ожидалось (см. FS-1019 ).

Когда я ссылаюсь на функцию из другого файла, открывая модуль Domain следующим образом, все хорошо:

module DTO_working
  open Domain

  let ti = TodoID 1
  let i1 = TodoID.value ti // Happiness

Однако, когда у меня есть файл, в котором я не открываю модуль, а пытаюсь полностью квалифицировать функцию, я не могу заставить его работать:

module DTO_broken
  let ti = Domain.TodoID 1
  let i1 = Domain.TodoID.value ti // error FS0039: The field, constructor or member 'value' is not defined.
  let i2 = Domain.TodoIDModule.value ti // error FS0039: The value, constructor, namespace or type 'TodoIDModule' is not defined

При наведении указателя мыши на часть value в Domain.TodoID.value в Visual Studio полное имя корректно отображается как Domain.TodoIDModule.value.

Когда я вручную добавляю суффикс Module и печатаю его везде , оно работает.

Чего мне не хватает? Можно ли ссылаться на функцию с автоматическим c суффиксом «Модуль», не открывая модуль?

Заранее благодарен за любую помощь,

Roland

1 Ответ

2 голосов
/ 29 января 2020

Во-первых, позвольте мне начать с того, что это должно работать.

Я начал с F # тестов с суффиксом автоматического модуля :

module Ok1

module A =
    let create() = 1
    type Dummy = A | B


type A = 
    member x.P = 1

let works = (typeof<A.Dummy>.FullName.Contains("AModule"))

Это работает хорошо. Похоже, что случай с DU имеет одно и то же имя.

Но есть тестовый случай, который охватывает это :

module Ok13

type A = A of string

module A = 
    let create() = 1
    type Dummy = A | B

Но в другом файле

module Ok13Test

let i1 = Ok13.A.create ()

не работает. Также нет проблем, если регистр TodoId DU был изменен на TodoIDCase:

type TodoID = TodoIDCase of int

module TodoID =
    let public value (TodoIDCase i) = i

Проблема не в генерировании суффикса модуля, что он делает правильно (проверено IL), а в выводе типа, присваивающем более высокая видимость к корпусу DU. Если вы уменьшите видимость,

type private A = A of string

снова начнет работать. Похоже, это проблема с выводом типа, поэтому, вероятно, лучше сейчас провести рефакторинг случая DU и отправить отчет об ошибке.

...