我有一个包含功能的记录类型:
{foo : int; bar : int -> int}
Run Code Online (Sandbox Code Playgroud)
我希望这种类型具有结构上的平等性.有什么方法可以说明bar在相等测试中应该忽略它吗?或者还有其他方法吗?
我知道F#有MAP,但我想使用.NET Dictionary.这个字典有字符串和值作为F#值+字典,即:
type ExprC =
| StrC of string
| BoolC of bool
| IntC of int32
| DecC of decimal
| ArrayC of int * array<ExprC>
| RelC of RelationC
and RelationC = Dictionary<string, ExprC>
Run Code Online (Sandbox Code Playgroud)
现在,我想解决的问题是如何为RelationC类型提供结构相等性.如果需要封装实际存储,如何创建一个替代Dictionary的容器,将其用于可变操作并具有结构相等性?
有了当前的答案,这段代码不起作用(诅咒实现不完整,但是,这甚至没有编译):
[<CustomEquality; CustomComparison>]
type MyDict() =
inherit Dictionary<string, ExprC>()
override this.Equals x =
match x with
| :? MyDict as y -> (this = y)
| _ -> false
override this.GetHashCode () =
hash this
interface System.IComparable with
member x.CompareTo yobj =
match …Run Code Online (Sandbox Code Playgroud) 我已经阅读了与我类似的各种问题,但它们似乎都没有解决我的问题.
我是这样的类型:
class MyObject<T> : IEquatable<MyObject<T>> { // no generic constraints
private readonly string otherProp;
private readonly T value;
public MyObject(string otherProp, T value)
{
this.otherProp = otherProp;
this.value = value;
}
public string OtherProp { get { return this.otherProp; } }
public T Value { get { return this.value; } }
// ...
public bool Equals(MyObject<T> other)
{
if (other == null)
{
return false;
}
return this.OtherProp.Equals(other.OtherProp) && this.Value.Equals(other.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
什么时候T是标量,因为MyObject<int>平等正常,但是当我定义像MyObject<IEnumerable<int>>平等失败时. …
如果我有这样的记录:
type MyDate =
{ Year : int
Month : int
Day : int }
Run Code Online (Sandbox Code Playgroud)
我知道 F# 的结构比较将确保在对列表进行排序时,它将保持一致的顺序。
我的问题是我是否可以依靠它以特定方式进行比较,这种方式是什么?
例如MyDate上面的记录:如果它按照声明的顺序比较每个字段,那么我可以假设以下内容:
{ Year: 2010; Month: 9: Day: 8 } > { Year: 2009; Month: 10; Day: 20 }
我一直在努力寻找描述 Record 类型的结构相等性如何工作的文档。我可以从 Fsharp.Core 测试中看到元组比较是如何工作的:https : //github.com/fsharp/fsharp/blob/cb6cb5c410f537c81cf26825657ef3bb29a7e952/tests/fsharp/core/attributes/test.fsx , but I can't'为 Record 类型找到类似的测试。
在F#中:
[0] = [0] = true
Run Code Online (Sandbox Code Playgroud)
在C#或.NET BCL中一般:
StructuralComparisons.Equals(new int[] { 0 }, new int[] { 0 }) == false
Run Code Online (Sandbox Code Playgroud)
为什么?
后记:
我认为我有"正确"等于的原因是因为事实证明这是真的:
var a = new { X = 3, Y = new { Z = -1 } };
var b = new { X = 3, Y = new { Z = -1 } };
StructuralComparisons.Equals(a, b) == true;
Run Code Online (Sandbox Code Playgroud) 总的来说,Kotlin中的每个设计决策本身都很棒,并且可以很好地过渡到Java。作为一名Java开发人员,您可以开始将其中的Kotlin视为具有更少样板的更简洁的Java进行编码,然后平稳地进入函数式编程等更高级的方面。
然而,我想知道的一件事是为什么其设计者决定做出==与“行为相同”的行为equals,然后引入===参照相等性检查。我可以想像试图吸引其他Java开发人员参与其中,让他们看到您的Kotlin代码,然后思考:“哦,不,应该在等号调用的整个地方进行引用检查!”
离开Java约定的思路是什么?为了明确起见,我完全了解Kotlin 和==或之间的区别,我只是想知道为什么。equals===