Можете ли вы объяснить, почему один работает, но не другой?Почему currying с obj не работает?
Учитывая
//fu : unit -> unit
let fu() =();;
Это работает
//exec : (unit -> unit) -> int -> unit
let exec (f:(unit -> unit)) (data:int) = f();;
//this works, and p : int -> unit
let p = exec fu;;
И это работает для других типов, таких как data
string
, long
и т.д.
Это не Работа
//exec : (unit -> unit) -> obj -> unit
let exec (f:(unit -> unit)) (data:obj) = f();;
let p = exec fu;;
и я получаю следующее сообщение об ошибке:
error FS0030: Value restriction. The value 'p' has been inferred to have generic type val p : ('_a -> unit)
Either make the arguments to 'p' explicit or, if you do not intend for it to be generic, add a type annotation.
Обратите внимание, единственное различие между этими случаями является тип параметра data
. Если obj
или System.Object
или 'a
- не работает.
Другое дело, что если data
имеет тип obj
то происходит следующее:
//Data type is obj
let exec (f:(unit -> unit)) (data:obj) = f();;
//specifying parameters explicitly
let p x = exec fu x;;
Теперь p
имеет подпись 'a -> unit
, не obj -> unit
.
Так что вопрос: почему «shortcuted» Выделка не работает, когда data
является obj
или 'a
и почему тип p
является 'a -> unit
когда data
был obj
?
Так я предполагаю, что это ошибка или ограничение умозаключения # типа F?Потому что для меня у компилятора достаточно информации для обобщения на то, что может работать, скажем, вообще не изменять тип параметра 'data'. –
@AlexeyRaga - Я думаю, что лучше всего рассматривать это как ограничение вывода F #. –