我正在尝试从数据库中加载所有Categories
,然后将它们映射到Map
(字典?),但是当我使用以下代码时:
[<StructuralComparison>]
type Category = {
mutable Id: string;
Name: string;
SavePath: string;
Tags: ResizeArray<Tag> }
let categories = session.Query<Category>()
|> Seq.map(fun z -> (z,0))
|> Map.ofSeq
它只会抛出一个错误:
结构,记录或联合类型 '类别'有 'StructuralComparison'属性但是 组件类型'ResizeArray' 不满足'比较' 约束
我完全不知道该怎么做,所以感谢任何帮助!
答案 0 :(得分:5)
此处的问题是,通过向StructuralComparison
类型添加Category
属性,您在比较Category
的实例时要求F#使用结构比较。简而言之,它将逐个比较每个成员,看它们是否相等,以确定Category
的两个实例是否相等。
这会对Category
的每个成员施加一个隐式约束,使其自身具有可比性。类型ResizeArray<Tag>
正在生成错误,因为它无法比较。大多数集合类型都是如此。
为了消除此错误,您需要使ResizeArray<T>
类型具有可比性,或者为Map
选择不同的密钥。 Don有一篇很棒的博客文章,深入探讨了这一主题,并提供了许多不同的方法来实现这一目标。这非常值得阅读
答案 1 :(得分:5)
F#正在抱怨ResizeArray<_>
不支持结构比较。 ResizeArray<_>
实例是可变的,不支持结构比较,因此您不能将它们用作记录字段,这些字段用作Map<_,_>
的键(按键排序)。您有几个选择:
让Tags
使用支持结构比较的集合类型(例如不可变Tag list
)。
使用[<CustomComparison>]
代替[<StructuralComparison>]
,这需要实施IComparable
。
使用可变字典(或其他相关集合类型)而不是Map
。例如,尝试使用dict
函数代替Map.ofSeq
。