FS0001: Error from adding type equation

This message is given when a value is determined to have a type that doesn't unify with a type that has been expected.

The following code demonstrates a simple version of the error:

let booleanBinding: bool = 10

This code results in the following output:

error FS0001: This expression was expected to have type
but here has type

Here, the type of the booleanBinding is required to be bool by the type annotation. However the value 10 is inferred to be int. Because int is not the same as bool, this message is reported.

This message can be issued in many different circumstances, and they all follow this same pattern. Type inference (or programmer-given type annotations) 'fixes' the type of a function or value to a certain type, and then later that type is used as if it were of a different type than the 'fixed' type. The following code demonstrates a more complex version of the error, where inference across functions causes the error to appear far away from where you might expect:

// this function has type `int -> int`.
// `+` takes the type of the arguments passed to it, and `1` is of type `int`, so
// `+` must be of type `int -> int`
let addOne i = i + 1

// this function has type `int -> int`, which may be surprising because no types are explicitly specified.
// the `printfn` call on the first line is of type `'a -> unit`, because `printfn "%A"` takes a value of any type and returns unit.
// this means that the type of the `i` parameter hasn't yet been decided based on how the parameter is used.
// the `addOne` call on the second line is of type `int -> int`, because `addOne` is of type `int -> int` (see above).
// this means that `i` _must_ be of type `int`, so the overall type signature of `printThenAdd` is inferred to be `int -> int`
let printThenAdd i =
    printfn "%A" i
    addOne i

// this line triggers the error
// > This expression was expected to have type
// >   'int'
// > but here has type
// >   'string'
// because `printThenAdd` has been inferred to have type `int -> int`, but a string was passed in as the `int` parameter
printThenAdd "a number"
|> ignore

To solve this message, you must change one of the two parts of the binding: the type annotation or the value binding.

  • If the value is correct, change or remove the type annotation.

  • If the type annotation is correct, check the value bound and ensure that no logic errors have been made.