Записи F #: поля с одинаковыми именами - PullRequest
8 голосов
/ 08 марта 2011

Пожалуйста, рассмотрите следующие определения записи:

type A = { F1 : int; F2 : int }
type B = { F1 : int; F3 : int } 

// error FS0656: This record contains fields from inconsistent types   
let a1 = { F1 = 1; F2 = 2 } 

// this works
let a2 = { A.F1 = 1; F2 = 2 }

Я не понимаю, почему a1 приводит к ошибке.

Все примеры, которые я мог найти, почему вы должны сделать это a-way, предполагают, что все имена полей в A и B имеют одно и то же имя - что, конечно, неоднозначно, но не должно Aи B быть различимым при наличии хотя бы одного отдельного поля?

Может быть, это просто способ, которым F # оценивает это, и добавление имени типа в первое поле, конечно, не составляет большого труда, но мне просто любопытно.

РЕДАКТИРОВАТЬ: Спасибо за ответы, которые помогли мне заметить нечто довольно странное: весь фрагмент работает, когда я оцениваю его в первый раз (ALT + Enter в VS 2010).

Когда я пытаюсь оценить второй раз, я получаю сообщение об ошибке.

Если никто не может воспроизвести это, моя установка VS, вероятно, не работает ...

EDIT2 (хорошо, время создавать учетную запись здесь, извините за правки) Спасибо wmeyer (и всем остальным)за то, что нашли время взглянуть на проблему и дать понять, что я неправильно понимаю, как работает FSI.Все прояснилось сейчас!

Ответы [ 3 ]

6 голосов
/ 08 марта 2011

Я не думаю, что ваша установка не работает.

Имеет смысл, что код не работает при оценке во второй раз.Старые типы A и B все еще существуют, они просто затенены .
Имена полей, с другой стороны, никогда не затеняются.(В противном случае вы никогда не могли бы иметь одно и то же имя поля в двух разных записях.)
«Объединение всех возможных записей» (см. Ответ массива) теперь имеет более одного элемента: старый (затененный) A и новыйA.

Чтобы решить эту проблему, вы можете использовать «Сброс сеанса» из интерактивного контекстного меню F # между выполнениями.Или оберните ваш код в модуль (тогда старые типы записей не будут ни доступны, ни доступны).

5 голосов
/ 08 марта 2011

только что проверил с помощью fsi, этот код работает

type A = { F1 : int; F2 : int }
type B = { F1 : int; F3 : int } 
let a1 = { F1 = 1; F2 = 2 } 

может быть, у вас есть что-то еще, что не было упомянуто в вашем посте, что вызывает эту двусмысленность?

3 голосов
/ 08 марта 2011

Действительно, это звучит так, как будто должно работать - начиная с спецификации :

Если field-labeli - это не один идентификатор, или начальный тип является типом переменнойзатем метка поля разрешается путем выполнения Разрешения метки поля (см. §14.1) для field-labeli, что приводит к набору полей FSeti.Каждый элемент этого набора имеет соответствующий тип записи, в результате чего получается набор типов записей RSeti.Пересечение всех RSeti должно дать один тип записи R, и каждое поле затем разрешается в соответствующее поле в R.

Что подразумевает объединение всех возможных записей, содержащих эти поляидентификаторы сводятся к одному типу записи, тогда это допустимо.Какой компилятор вы используете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...