此类型定义有效:
type Model<'t,'u when 't :> seq<'u> >(query: unit -> 't) = class end
Run Code Online (Sandbox Code Playgroud)
但是,对我来说,'u这里是多余的,但下一个定义是:
type Model<'t when 't :> seq<_> >(query: unit -> 't) = class end
Run Code Online (Sandbox Code Playgroud)
产生错误:
此声明中不允许使用匿名类型变量-
F# Compiler (715)
最紧凑的形式:
type Model<'t>(query:unit -> #seq<'t>) = class end
Run Code Online (Sandbox Code Playgroud)
在实例创建过程中:
Query.users |> Model
Run Code Online (Sandbox Code Playgroud)
产生错误:
类型约束不匹配。类型
unit -> (string * int) list
与类型不兼容unit -> 'a
F# Compiler (193)
可能是由于此处所述,为什么记录类型定义中不允许使用灵活类型?。但是无论如何,错误说明对我来说还是不清楚的,用(string * int) list代替代替有'a什么问题?
实类型Model是数据库查询的包装,它实现INotifyPropertyChanged并包含mutabletype的状态Outcome:
type 't Outcome =
| Empty
| Loading
| Success of 't
| Fault of string * string
Run Code Online (Sandbox Code Playgroud)
在#seq<'t>需要类型约束检测Empty用的情况下Seq.isEmpty在通用的方式,由于查询可返回seq或list或array
正如@kvb所解释的那样,问题在于您不能具有泛型构造函数-因此您可以在整个类中引入新的类型参数(如您在第一个示例中所做的那样),或者返回类型query必须为seq<'t>(因为编译器会迫使您在其他示例中执行此操作)。
如果要将事情封装在一个类中,一个不错的技巧是使构造函数私有并添加一个静态Create方法,该方法可以具有所需的额外泛型参数:
type Model<'t> private(query:unit -> seq<'t>) =
static member Create(query:unit -> #seq<'t>) =
Model(fun () -> query () :> _)
Run Code Online (Sandbox Code Playgroud)