F# 泛型函数的类型推断变通方法
给定以下参数化类型F# 泛型函数的类型推断变通方法,f#,type-inference,F#,Type Inference,给定以下参数化类型 type SomeDU2<'a,'b> = | One of 'a | Two of 'a * 'b 这非常好,正如预期的那样 let oi = checkOne (One 1) let os = checkOne (One "1") let tis = checkTwo (Two (1, "1")) let tsi = checkTwo (Two ("1", 1)) 我可以随意切换类型。 现在我想把这两个函数合并成一个创建函数 let ma
type SomeDU2<'a,'b> =
| One of 'a
| Two of 'a * 'b
这非常好,正如预期的那样
let oi = checkOne (One 1)
let os = checkOne (One "1")
let tis = checkTwo (Two (1, "1"))
let tsi = checkTwo (Two ("1", 1))
我可以随意切换类型。现在我想把这两个函数合并成一个创建函数
let makeUC () = (checkOne, checkTwo)
然后像这样实例化
let (o,t) = makeUC ()
只是现在它给了我这个错误信息
Value restriction. The value 'o' has been inferred to have generic type
val o : (SomeDU2<'_a,'_b> -> bool)
Either make the arguments to 'o' explicit or, if you do not intend for it to be generic, add a type annotation.
val o : (SomeDU2<obj,obj> -> bool)
因此,我必须为
SomeDU2
的每个泛型参数组合实例化一个特定的o
实例 即使没有元组,也会遇到值限制:
let o = (fun () -> checkOne)()
如果您需要调用函数的结果适用于任何类型的值,那么一种解决方案是使用泛型方法创建标称类型的实例:
type DU2Checker =
abstract Check : SomeDU2<'a,'b> -> bool
let checkOne = {
new DU2Checker with
member this.Check(x) =
match x with
| One _ -> true
| _ -> false }
let checkTwo = {
new DU2Checker with
member this.Check(x) =
match x with
| Two _ -> true
| _ -> false }
let makeUC() = checkOne, checkTwo
let o,t = makeUC()
let false = o.Check(Two(3,4))
DU2Checker型=
摘要检查:SomeDU2->bool
让checkOne={
新DU2Checker与
此成员。检查(x)=
将x与
|一个是真的
|_u->false}
让我们检查两个={
新DU2Checker与
此成员。检查(x)=
将x与
|两个->正确
|_u->false}
让makeUC()=checkOne,checkTwo
设o,t=makeUC()
设false=o.检查(两(3,4))
两个选项:要么按照错误消息所说的去做,要么使用o
消息可能会消失away@JohnPalmer由于您的评论,添加了更多信息。您计划如何使用函数元组?看起来很尴尬。“你想达到什么目的?”阿西巴希说
let ro2 = o ((One "1") : SomeDU2<string,int>)
let o = (fun () -> checkOne)()
type DU2Checker =
abstract Check : SomeDU2<'a,'b> -> bool
let checkOne = {
new DU2Checker with
member this.Check(x) =
match x with
| One _ -> true
| _ -> false }
let checkTwo = {
new DU2Checker with
member this.Check(x) =
match x with
| Two _ -> true
| _ -> false }
let makeUC() = checkOne, checkTwo
let o,t = makeUC()
let false = o.Check(Two(3,4))