generics - 如何让 F# 编译器将我的参数推断为泛型函数?

标签 generics f#

我编写了一些测试代码来了解泛型的语法:

let add_stuff<'T> x y =
   printfn "%A" (x + y)

let stuff() = 
    add_stuff 5.5 2.4
    add_stuff 3 4

第二个 add_stuff 调用无法编译。为什么是这样?为什么编译器不推断类型?

最佳答案

代码有 2 个问题:

首先,任何参数都不使用泛型类型'T。参数需要声明为 'T 类型,如下所示:

// val add_stuff: 'T -> 'T -> unit
let add_stuff<'T> (x:'T) (y:'T) =
    printfn "%A" (x + y)

这会创建一条新的错误消息:

The declared type parameter 'T' cannot be used here since the type parameter cannot be resolved at compile time

本例中的问题是 + 运算符。它使用静态解析类型参数,这意味着您的函数也需要使用它们,这基本上意味着它需要内联:

// val add_stuff: ^T -> ^T -> unit
let inline add_stuff (x:^T) (y:^T) =
    printfn "%A" (x + y)

注意类型签名的区别 'T 是泛型类型,它可以在运行时解析。 ^T 是一个 SRTP,需要在编译时解析,因此需要 inline 关键字。

如果您没有使用 + 运算符,则不需要内联它。请注意 pair_stuffadd_stuff 之间的区别:

// val pair_stuff: 'T -> 'W -> unit
let pair_stuff (x:'T) (y:'W) =
    printfn "%A" (x , y)

// val add_stuff:  ^a -> ^b -> unit
let inline add_stuff x y =
    printfn "%A" (x + y)

let stuff() = 
    add_stuff 5.5 2.4
    add_stuff 3 4
    pair_stuff 5.5 2.4
    pair_stuff 3 4

stuff()
// 7.9
// 7
// (5.5, 2.4)
// (3, 4)

关于generics - 如何让 F# 编译器将我的参数推断为泛型函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53523374/

相关文章:

1.3 版不支持 java 泛型和注释(travis 集成)

f# - ODataService 类型提供程序的可为空整数不存在属性 'HasValue'

f# - 如何包装 F# 类型以访问其属性

performance - 同步时 F# Akka.NET 代理性能优化

c# - 如何获取泛型类型参数的类型名称?

generics - CaSTLe Windsor Ioc 解析 web.config 中的通用类

c# - 如果我选择不同的通用约束,为什么不能重载具有相同参数的方法?

swift - 如何引用作为关联类型的协议(protocol)的属性?

.net - 即使 dll 与可执行文件位于同一文件夹中,DllImport 也找不到 dll

parameters - F#管道第一个参数