Здравствуйте, Ka3a4oK, Вы писали:
KK>Var.A().GetHashCode(), Var.B().GetHashCode() и т.д. будут возвращать отдно и то же значение — ноль. Это ок?
Это не фатально, но плохо. Пиши в трекер.
А еще лучше пофикси и сделай pull request.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Ka3a4oK, Вы писали:
KK>Var.A().GetHashCode(), Var.B().GetHashCode() и т.д. будут возвращать отдно и то же значение — ноль. Это ок?
Разные значения не предусмотрены макросом. Для вариантов нужен совсем отдельный способ генерации Equals/GetHashCode.
Исправить я не знаю как, потому что варианты реализованы с помощью наследования, а наследование и структурное равенство плохо комбинируются (в то же время, структурное равенство для вариантов — вещь нужная). Так что если есть предложения, высказывайте.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Ka3a4oK, Вы писали:
KK>>Var.A().GetHashCode(), Var.B().GetHashCode() и т.д. будут возвращать отдно и то же значение — ноль. Это ок?
VD>Проблемой это не является. Да и на практике редко встречаются вхождения без полей. VD>Но можно добавить ^ _N_GetVariantCode() к значению.
Тут хорошо сделать как в фшарпе, вхождения без полей используют значние 0, 1, 2 для хеш кода, в случае полей добавляется математика с полиномами, типа:
type Tree =
| A
| B
| C of string * int
[CompilerGenerated]
public sealed override int GetHashCode(IEqualityComparer comp)
{
if (this > null)
{
int num = 0;
Program.Tree tree = this;
if (!(tree is _A))
{
if (tree is _B)
{
_B _b = (_B) this;
return 1;
}
if (tree is C)
{
C c = (C) this;
num = 2;
IEqualityComparer comparer = comp;
num = -1640531527 + (c.item2 + ((num << 6) + (num >> 2)));
IEqualityComparer comparer2 = comp;
string str = c.item1;
return (-1640531527 + (((str != null) ? str.GetHashCode() : 0) + ((num << 6) + (num >> 2))));
}
}
_A _a = (_A) this;
}
return 0;
}
Здравствуйте, CodingUnit, Вы писали:
CU>в случае полей добавляется математика с полиномами, типа:...
Ничего хорошего в этом нет. Это маразм. Расчет хэш-код должен быть максимально быстрым. Иначе он теряет смысл.
Единственное что нужно от хэш-кода это более менее хоршее распределение. Я по тестировал текущий вариант на реальных примерах. Работает не плохо.
Потом суть последних изменений в том, что макрос работает универсально для всех иерархий типов. Варианты тут только частный случай. Делать под него заточку смысла нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ничего хорошего в этом нет. Это маразм. Расчет хэш-код должен быть максимально быстрым. Иначе он теряет смысл.
Я привел пример подчистую что делает фшарп, я хотел показать только математику, которая решает проблему, само собой эти проверки может сделать более проще, без лишней динамики, но должно быть обязательное различие типов:
| A
| B { val : int; }
где val = 0, раньше и у первого и второго вложения был хэш код 0, надо учитывать и поля и пустые вложения, через маски полиномов, я думаю.
VD>Потом суть последних изменений в том, что макрос работает универсально для всех иерархий типов. Варианты тут только частный случай. Делать под него заточку смысла нет.
Все же варианты это отдельные сущности, которые имеют логическую связь с друг другом, распределение должно быть по всем им и никогда не пересекаться.
Здравствуйте, catbert, Вы писали:
C>А что там медленного? Суммы и шифты.
Там и динамических проверок типов выше крыши, и вычисления слишком сложные. Это явный овердизайн. Качества хэша он если и повысит, то на доли процента, а вот время его расчета замедлит.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.