Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här meddelandet ges när ett värde bestäms ha en typ som inte förenas med en typ som har förväntats.
Följande kod visar en enkel version av felet:
let booleanBinding: bool = 10
Den här koden resulterar i följande utdata:
error FS0001: This expression was expected to have type
'bool'
but here has type
'int'
Här är den typ av booleanBinding som krävs för att vara bool av typen anteckning. Värdet 10 härleds dock till int. Eftersom int inte är samma som boolrapporteras det här meddelandet.
Det här meddelandet kan utfärdas under många olika omständigheter och alla följer samma mönster. Typinferens (eller annoteringar av programmerare) "korrigerar" typen av en funktion eller ett värde till en viss typ, och senare används den typen som om den hade en annan typ än den fasta typen. Följande kod visar en mer komplex version av felet, där slutsatsdragning mellan funktioner gör att felet visas långt ifrån där du kan förvänta dig:
// 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
Partiell program- och typinferens
Ett annat vanligt scenario där det här felet inträffar är delvis tillämpning av funktioner. När du definierar en funktion med flera parametrar med bindningarlet behandlar F# den som en curryfunktion. Det innebär att om du använder färre argument än vad funktionen förväntar sig returneras en ny funktion som förväntar sig de återstående argumenten, som du ser i följande exempel:
// 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'
I det här exemplet Sum är en funktion med typen int -> int -> int. När du skickar det till RegisterFunction1mappar 'A typinferenssystemet till int och 'B till int -> int (den delvis tillämpade funktionen). Men när du försöker skicka det till RegisterFunction2, vilket förväntar sig 'A -> int, identifierar typsystemet korrekt som Sum returnerar int -> int (en funktion), inte int (ett värde), vilket orsakar typmatchningsfelet.
Mer information om hur F# hanterar funktionsdefinitioner och partiella program finns i Funktioner.
Så här åtgärdar du det här felet
För att lösa det här meddelandet måste du ändra en av de två delarna i bindningen: typanteckningen eller värdebindningen.
Om värdet är korrekt ändrar eller tar du bort typanteckningen.
Om typanteckningen är korrekt kontrollerar du värdet som är bundet och ser till att inga logikfel har gjorts.