Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 泛型函数的类型推断变通方法_F#_Type Inference - Fatal编程技术网

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))