#f# #value-restriction
#f# #ограничение по значению
Вопрос:
Я получаю ошибку VR при привязке let к области видимости модуля, в которой говорится, что один из его параметров является общим, но я не знаю, почему этот параметр является общим в первую очередь. Это код:
let private asJsonResponse (responseSource: _ Task) =
fun (next: HttpFunc) (ctx: HttpContext) ->
task {
let! consumption = responseSource
return! json consumption next ctx
}
let getVal = someFuncThatReturnsTaskOfMyType() |> asJsonResponse
Ошибка находится в последней строке:
ошибка FS0030: ограничение значения. Предполагается, что значение
getVal
имеет общий типval getVal: (HttpFunc -> '_a -> Task<HttpContext option>)
, если'_a :> HttpContext
либо сделать аргументыgetVal
явными, либо, если вы не хотите, чтобы оно было общим, добавить аннотацию типа.
Я понимаю, что оно по существу обобщается ctx: HttpContext
на что-то, к чему можно привести HttpContext
. Почему это происходит? И почему только для этого параметра, а не next: HttpFunc
?
HttpContext
это класс и HttpFunc
это тип функции, в этом проблема?
Комментарии:
1. Вы уверены, что это именно тот код, с которым вы работаете? Может быть, вы забыли перекомпилировать модуль после внесения изменений?
2. @FyodorSoikin Я выполнил полную перестройку перед публикацией здесь, чтобы убедиться, что код скопирован из моего исходного файла (за исключением некоторых изменений имени).
3. Попробуйте добавить аннотации типов повсюду и посмотрите, что произойдет. В этом случае я предполагаю
asJsonResponse
, что это должна делать аннотация типа on .
Ответ №1:
Он компилируется, если вы добавляете аннотации типов:
let getVal: HttpFunc -> HttpContext -> Task<HttpContext option> =
someFuncThatReturnsTaskOfMyType() |> asJsonResponse
Или добавьте явный параметр:
let getVal f = asJsonResponse (someFuncThatReturnsTaskOfMyType()) f
Простой ответ заключается в том, что механизм вывода типов компилятора F # не идеален. Вы можете прочитать об этом здесь :
Компилятор F # пытается угадать наиболее обобщенный тип, который подходит, но в некоторых случаях компилятор чувствует, что код неоднозначен, и, хотя кажется, что он угадывает тип правильно, ему нужно, чтобы вы были более конкретными
и для получения более подробной информации, вот документация:
Автоматическое обобщение MSDN в F # имеет несколько примеров этого
Обычно ошибка ограничения значения возникает либо когда вы хотите, чтобы конструкция была универсальной, но у компилятора недостаточно информации для ее обобщения, либо когда вы непреднамеренно опускаете достаточную информацию о типе в негенеральной конструкции.