在私有联合类型上公开比较/相等

时间:2011-06-05 19:04:04

标签: f#

我正在努力在隐藏案例的联合类型上公开比较/相等。这就是我的开始:

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 = ...'.

这是将联合类型与私有案例进行比较的正确方法吗?签名文件中的正确语法是什么?

1 个答案:

答案 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