2010-04-21 3 views
5

В F # оператор равенства (=), как правило, является экстенсиональным, а не интенсиональным. Замечательно! К сожалению, мне кажется, что F # не использует равенство указателя, чтобы сократить эти экстенсиональные сравнения.проверка равенства в F #?

Например, этот код:

 
type Z = MT | NMT of Z ref 

// create a Z: 
let a = ref MT 
// make it point to itself: 
a := NMT a 

// check to see whether it's equal to itself: 
printf "a = a: %A\n" (a = a) 

... дает мне большую ошибку сегментации жира [*], несмотря на то, что «а» и «а» и оценить в той же ссылке. Это не так здорово. Другие функциональные языки (например, PLT Scheme) получают это право, используя консервативные сравнения указателей, чтобы вернуть «true», когда это можно определить с помощью сравнения указателей.

Итак: я согласен с тем, что оператор равенства F # не использует короткую резку; есть ли какой-нибудь способ выполнить проверку на основе измерения (на основе указателя)? Оператор (==) на моих типах не определен, и мне бы это понравилось, если кто-то мог сказать мне, что он доступен как-то.

Или скажите мне, что я неправильно в моем анализе ситуации: Я хотел бы, что тоже ...

[*] Это, вероятно, будет переполнение стека на Windows; есть вещи о Моно, что я не так люблю ...

ответ

7

Есть два варианта, о которых я знаю. Стандартный подход .NET должен был бы использовать System.Object.ReferenceEquals. Немного лучший подход в F # может заключаться в использовании LanguagePrimitives.PhysicalEquality, который в основном идентичен, но работает только на ссылочных типах (что, вероятно, правильно для ваших целей) и требует, чтобы оба аргумента имели один и тот же статический тип. Вы также можете определить пользовательский оператор по вашему выбору с точки зрения любой из этих функций, если вам нужен более сильный синтаксис.

Как в стороне, на .NET Я получаю бесконечный цикл, но не переполнение стека, когда я запускаю ваш код, по-видимому, из-за оптимизации хвостового вызова.

+0

Спасибо! В стороне: да, это действительно сбрасывает ядро ​​на mono/osx. Возможно, вызов хвоста не выполняется должным образом для проверки равенства в конкретной комбинации mono/fsharp, которую я использую. –

Смежные вопросы