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#_Pattern Matching_Type Inference - Fatal编程技术网

F# 过度攻击型推理?

F# 过度攻击型推理?,f#,pattern-matching,type-inference,F#,Pattern Matching,Type Inference,因此,在处理一些问题时,我希望能够取整数值(int、long、bigint等)的平方根,但Sqrt仅为浮点值定义。所以我一直在写我自己的小牛顿-拉斐逊算法,它对于我所需要的非常精确。但是,我希望能够对浮点值调用内置的sqrt函数。所以我写了这样的东西: let inline dsqrt x = match box x with | :? float -> sqrt x | :? float32 -> sqrt x | _ -> p_dsqrt x

因此,在处理一些问题时,我希望能够取整数值(int、long、bigint等)的平方根,但Sqrt仅为浮点值定义。所以我一直在写我自己的小牛顿-拉斐逊算法,它对于我所需要的非常精确。但是,我希望能够对浮点值调用内置的sqrt函数。所以我写了这样的东西:

let inline dsqrt x =
    match box x with
    | :? float -> sqrt x
    | :? float32 -> sqrt x
    | _ -> p_dsqrt x

显然,我的函数名为“p_dsqrt”。然而,这个函数要求输入定义一个Sqrt方法,这有点违背了整个目的。我是否缺少某种类型约束,或者什么?

我想您可能希望这样:

let dsqrt x =
    match box x with
    | :? float as f -> sqrt f |> box :?> 'a
    | :? float32 as f -> sqrt f |> box :?> 'a
    | _ -> p_dsqrt x

代码的问题是您直接调用了
sqrt x
,这限制了
x
的可能类型。在我修改的代码中,我将一个新的标识符绑定到成功强制到
float
float32
的结果,因此这不会对
x

的类型施加任何约束。如果要使用匹配,则不需要内联关键字,但如果要使用内联函数和“帽子类型”,使用重载而不是匹配:

type Sqrt = Sqrt with
    // Dummy overload in order to get the right types inferred (will never reach here)
    static member inline ($) (Sqrt, _:^t when ^t:null and ^t: struct) = id

    // Existing sqrt
    static member inline ($) (Sqrt, x:'a) :'a = sqrt x 

    // Your Newton-Raphson based sqrt's
    static member        ($) (Sqrt, x:int   ) = sqrtForInt    x
    static member        ($) (Sqrt, x:bigint) = sqrtForBigInt x 

let inline sqrt (x:'t) :'t = Sqrt $ x 
返回类型将始终与输入类型相同,所选sqrt的实现将取决于该类型。此选择将发生在编译时,这是与在运行时解析的match方法的主要区别


如果我去掉伪重载,它将与您的代码有相同的问题:它将需要sqrt约束。

如果它有用,下面是我在Euler问题中用于整数平方根的代码:预期的返回类型是什么?但是,
dsqrt
不应该仍然是
内联的
,要正确地将
x
的类型传播到
p\u dsqrt
?不幸的是,我现在遇到了一个不同的错误。我得到“类型‘float’与类型‘float32’不匹配”。当我删除'float32'案例时,函数仍然解析为“float->float”。作为参考,我的p_dsqrt函数解析为“'a->'a”。@leecarbtree-对不起,我更新了我的答案。还需要动态转换回泛型类型。哇,这太棒了:)这是如何工作的?我看不懂我在读什么!但结果令人印象深刻。