0
votes

Why is f inferred to be of type obj -> int and not seq<'T> -> int ?

  let fseq (o:'T seq) : int = 0                  //val fseq : o:seq<'T> -> int
  let f = match true with                        //f : obj -> int
                  | true ->  fun o -> fseq o
                  | false -> failwith ""

That leads to strange message such as the following later

  let a : (obj -> int ) list = []
  let a' = f::a  //error yet type inference says f : obj -> int 

ps : not really a problem, inference always has a limit and it is quite powerful in fsharp, but I am wondering why the type would be unified to obj in here.

2
For me this gives a value restriction but does come close to giving the correct type. What version of F# are you using? - John Palmer

2 Answers

2
votes

The first error is a typical value restriction.

In f# functions can be generic, not constants. You can solve it as any other value restriction, for example moving the argument to the left side of the =:

let f o = match true with                    
              | true  -> fseq o
              | false -> failwith ""

Regarding the second error it's confusing what you see. The code is not compiling because of the first error but intellisense is telling you another thing.

It's normal, specially when the code is not compiling that intellisense tells you something else, sometimes it infers the correct type but not the compiler, they are not always in sync.

1
votes

The problem is with second part of Your code - a is (obj -> int ) list while it should be (obj seq -> int ) since it is type of fseq function. The following codes works well.

let fseq (o : 'T  seq) : int = 0             
let f = match true with                        
        | true ->  fun o -> fseq o
        | false -> failwith ""

let a : (obj seq -> int ) list = []
let a' = f::a