다음을 통해 공유


FS0001: 형식 수식을 추가하는 동안 오류가 발생했습니다.

이 메시지는 값에 예상된 형식과 통합되지 않는 형식이 있는 것으로 확인될 때 제공됩니다.

다음 코드는 오류의 간단한 버전을 보여 줍니다.

let booleanBinding: bool = 10

이 코드는 다음과 같은 출력을 생성합니다.

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

여기서 형식 주석을 booleanBinding 사용하려면 bool 형식이 필요합니다. 그러나 값 10 은 .로 유추됩니다 int. int 이 메시지는 동일bool하지 않으므로 보고됩니다.

이 메시지는 다양한 상황에서 발행될 수 있으며 모두 동일한 패턴을 따릅니다. 형식 유추(또는 프로그래머가 지정한 형식 주석)는 함수 또는 값의 형식을 특정 형식으로 '수정'한 다음 나중에 해당 형식이 '고정' 형식과 다른 형식인 것처럼 사용됩니다. 다음 코드는 더 복잡한 버전의 오류를 보여 줍니다. 여기서 함수 간 유추로 인해 오류가 예상한 위치와 멀리 떨어져 표시됩니다.

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

부분 애플리케이션 및 형식 유추

이 오류가 발생하는 또 다른 일반적인 시나리오에는 함수의 부분 적용이 포함됩니다. 바인딩을 사용하여 여러 매개 변수를 사용하여 let 함수를 정의할 때 F#은 이를 curried 함수로 처리합니다. 즉, 함수에서 예상하는 것보다 적은 인수를 적용하면 다음 예제와 같이 나머지 인수를 예상하는 새 함수가 반환됩니다.

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

이 예제에서는 Sum 형식 int -> int -> int이 있는 함수입니다. 전달RegisterFunction1하면 형식 유추 시스템이 부분적으로 적용된 함수에 int 매핑 'A 됩니다 'Bint -> int . 그러나 예상되는 값에 RegisterFunction2전달하려고 하면 형식 시스템이 (값이 아닌 int ) 반환 int -> int 하는 함수를 올바르게 식별 Sum 하여 형식 불일치 오류가 발생'A -> int합니다.

F#이 함수 정의 및 부분 애플리케이션을 처리하는 방법에 대한 자세한 내용은 Functions를 참조하세요.

이 오류를 해결하는 방법

이 메시지를 해결하려면 바인딩의 두 부분 중 하나인 형식 주석 또는 값 바인딩 중 하나를 변경해야 합니다.

  • 값이 올바르면 형식 주석을 변경하거나 제거합니다.

  • 형식 주석이 올바른 경우 바인딩된 값을 확인하고 논리 오류가 발생하지 않았는지 확인합니다.