Why can't F # deduce type in this case?

Consider the following code example in which I have a common type and two static member constructors that create a specialized instance of the specified 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"

I think I have the necessary type annotations, but F # gives me warnings. For instance:

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<_>'.

How can I make the warning go away?

+4
source share
2 answers

As @ildjarn intended, it Cellis a generic type, and the compiler wants to know the type 'Twhen invoking the static member.

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

A way to avoid specifying 'Tis to move the creation functions to the 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 still specify the type you want in the function name, the following syntax may be preferable.

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 , , 'T Cell, .

+4

'T CreateInt CreateFloat, . :

Cell<float>.Create 1.0 // useless type annotation to remove warning

Cell<string>.Create 1.0 // Trollolol

, , factory , . factory , , .

, .

type Cell<'T> =
    { slot: 'T }
    static member Create (x : 'T) = { slot = x }

let x = Cell.Create 123
let y = Cell.Create "testing"

x, factory Cell<>!

:

, IntCell StringCell ; Cell<int> Cell<string>. , , Cell. , , , , .

: , . IntCell StringCell , , Cell . , .

+4

All Articles