FS0001: Fout bij het toevoegen van een typevergelijking

Dit bericht wordt weergegeven wanneer wordt bepaald dat een waarde een type heeft dat niet overeenkomt met een type dat is verwacht.

De volgende code demonstreert een eenvoudige versie van de fout:

let booleanBinding: bool = 10

Deze code resulteert in de volgende uitvoer:

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

Hier moet het type van de booleanBinding aantekening zijn bool . De waarde 10 wordt echter afgeleid.int Omdat int dit niet hetzelfde is als bool, wordt dit bericht gerapporteerd.

Dit bericht kan in veel verschillende omstandigheden worden uitgegeven en ze volgen allemaal hetzelfde patroon. Typ deductie (of door programmeurs opgegeven typeaantekeningen) 'corrigeert' het type van een functie of waarde voor een bepaald type en later wordt dat type gebruikt alsof het een ander type is dan het 'vaste' type. De volgende code demonstreert een complexere versie van de fout, waarbij deductie tussen functies de fout ver weg van de verwachte fout veroorzaakt:

// 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

Gedeeltelijke toepassing en type deductie

Een ander veelvoorkomend scenario waarbij deze fout optreedt, omvat gedeeltelijke toepassing van functies. Wanneer u een functie met meerdere parameters definieert met behulp van let bindingen, behandelt F# deze als een curriede functie. Dit betekent dat het toepassen van minder argumenten dan de functie verwacht, een nieuwe functie retourneert die de resterende argumenten verwacht, zoals wordt weergegeven in het volgende voorbeeld:

// Define a function that takes two arguments and returns their sum
let Sum x y = x + y

// This works: RegisterFunction1 accepts a function with generic types 'A -> 'B
// When passed Sum (which is int -> int -> int), type inference maps:
// 'A to int (the first parameter type)
// 'B to int -> int (the remaining function after partial application)
let RegisterFunction1 (fn:'A->'B) = ()
let Test1 = RegisterFunction1 Sum

// This fails: RegisterFunction2 expects a function 'A -> int (returning int, not a function)
// When passed Sum (which is int -> int -> int), type inference maps:
// 'A to int (the first parameter type)
// But then expects the return type to be int, not int -> int (the partially applied function)
let RegisterFunction2 (fn:'A->int) = ()
// Uncommenting the next line would trigger the error:
// > This expression was expected to have type
// >   'int -> int'
// > but here has type
// >   'int -> int -> int'

In dit voorbeeld Sum is een functie met het type int -> int -> int. Wanneer u deze RegisterFunction1doorgeeft, wordt het type deductiesysteem toegewezen 'A aan int en 'B aan int -> int (de gedeeltelijk toegepaste functie). Wanneer u het echter probeert door te geven aan RegisterFunction2, wat verwacht 'A -> int, identificeert het typesysteem correct dat Sum retourneert int -> int (een functie), niet int (een waarde), waardoor het type fout niet overeenkomt.

Zie Functions voor meer informatie over hoe F# functiedefinities en gedeeltelijke toepassing verwerkt.

Deze fout oplossen

Als u dit bericht wilt oplossen, moet u een van de twee delen van de binding wijzigen: het typeaantekening of de waardebinding.

  • Als de waarde juist is, wijzigt of verwijdert u de aantekening van het type.

  • Als de typeaantekening juist is, controleert u de waardegrens en zorgt u ervoor dat er geen logische fouten zijn gemaakt.