我正在努力在隐藏案例的联合类型上公开比较/相等。这就是我的开始:
Module.FSI
type A<'T when 'T : comparison>
Module.FS
type A<'T when 'T : comparison> = A of 'T list
Program.FS
[<StructuralEquality;StructuralComparison>]
type B =
| Case1
| Case2 of Module.A<char>
但我收到错误:
The struct, record or union type 'B' has the 'StructuralComparison'
attribute but the component type 'Module.A<char>' does not satisfy the
'comparison' constraint
我尝试在A:
上使用自定义相等Module.FSI
[<CustomEquality;CustomComparison>]
type A<'T when 'T : comparison>
with
interface System.IComparable
override Equals : y:obj -> bool
override GetHashCode : unit -> int
end
Module.FS
[<CustomEquality;CustomComparison>]
type A<'T when 'T : comparison> = A of 'T list
with
override x.Equals y = ...
override x.GetHashCode() = ...
interface System.IComparable with
member x.CompareTo(y) = ...
但我明白了:
This construct is deprecated: The syntax 'type X with ...' is reserved
for augmentations. Types whose representations are hidden but which have
members are now declared in signatures using 'type X = ...'.
这是将联合类型与私有案例进行比较的正确方法吗?签名文件中的正确语法是什么?
答案 0 :(得分:2)
错误消息仅表示FSI文件声明的正确语法应使用=
(如实现文件中)而不是with ... end
语法。但是,这并没有真正解决问题。经过一些实验,我认为您不需要在FSI文件中应用这些属性:
// Mod.fs
namespace Mod
[<CustomEquality; CustomComparison>] //; CustomEquality>]
type A<'T when 'T : comparison> =
| A of 'T list
override x.Equals y = compare x (y :?> A<_>) = 0
override x.GetHashCode() = -1
interface System.IComparable with
member x.CompareTo(y) = compare x (y :?> A<_>)
// Mod.fsi
namespace Mod
[<Sealed>]
type A<'T when 'T : comparison> =
interface System.IComparable
override Equals : obj -> bool
override GetHashCode : unit -> int
这应该可以解决问题 - 不幸的是,我不确定是否有办法使用自动生成的结构相等并同时隐藏受歧视联盟的实现。
编辑看起来您可以在FSI文件中指定有区别的联合案例,但将其标记为private
,因此它们在模块外部不可见。所以也许这也会奏效:
// Mod.fsi
namespace Mod
type A<'T when 'T : comparison> =
private | A of 'T list
// Mod.fs
namespace Mod
[<StructuralComparisonAttribute; StructuralEqualityAttribute>]
type A<'T when 'T : comparison> =
| A of 'T list