为什么在这种情况下F#无法推断类型? [英] Why can't F# infer the type in this case?

查看:88
本文介绍了为什么在这种情况下F#无法推断类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下示例代码,其中我有一个泛型类型和2个静态成员构造函数,它们创建了所述类型的专用实例.

Consider the following sample code where I have a generic type and 2 static member constructors that create a specialized instance of the said type.

type Cell<'T> = { slot: 'T }
with
    static member CreateInt x : IntCell  = { slot = x }
    static member CreateString x : StringCell = { slot = x}
and IntCell = Cell<int>
and StringCell = Cell<string>

// Warnings on the next 2 lines
let x = Cell.CreateInt 123
let y = Cell.CreateString "testing"

我认为我已经准备好了必要的类型注释,但是F#给了我警告.例如:

I think I have the necessary type annotations in place and yet F# gives me warnings. E.g:

Warning 2 The instantiation of the generic type 'Cell' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Cell<_>'.

Warning 2 The instantiation of the generic type 'Cell' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Cell<_>'.

如何使警告消失?

推荐答案

正如@ildjarn所暗示的,Cell是泛型类型,编译器希望在调用静态成员时知道类型'T.

As hinted by @ildjarn, Cell is a generic type and the compiler wants to know the type 'T when calling the static member.

// Two ways to fix the compiler warning
let x = Cell<int>.CreateInt 123
let y = StringCell.CreateString "testing"

避免指定'T的一种方法是将创建函数移到模块中.

A way to avoid specifying 'T is to move the create functions into a module.

type Cell<'T> = { slot: 'T }
type IntCell = Cell<int>
type StringCell = Cell<string>
module Cell =
    let createInt x : IntCell = { slot = x }
    let createString x : StringCell = { slot = x }

let x = Cell.createInt 123
let y = Cell.createString "testing"

但是,由于无论如何都要在函数名称中指定所需的类型,因此以下语法可能是首选.

However, since you specify the desired type in the function name anyway, the following syntax may be preferred.

type Cell<'T> = { slot: 'T }
with
    static member Create (x : 'T) = { slot = x }
type IntCell = Cell<int>
type StringCell = Cell<string>

let x = IntCell.Create 123
let y = StringCell.Create "testing"

// or simply
let z = Cell<float>.Create 1.0

感谢@Vandroiy指出了我的Create方法中缺少的类型约束,并给出了答案,该答案显示了编译器如何在可以通过静态方法确定泛型Cell的情况下推断出'T为泛型类型Cell被呼叫.

Thanks to @Vandroiy for pointing out the missing type constraint in my Create method and for his answer that shows how the compiler can infer 'T for the generic type Cell when it can be determined by the static method being called.

这篇关于为什么在这种情况下F#无法推断类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆