У меня проблемы с пониманием поведения логического вывода типа F #.Оператор string
полагается на статическую диспетчеризацию типа во время компиляции, а не во время выполнения, поэтому что-то вроде let lowerstring = string >> (fun s -> s.ToLowerInvariant())
не обобщается - компилятору необходимо знать тип аргумента.Однако я вижу странное для меня поведение.
Со следующими определениями:
let inline lower (s: string) = s.ToLowerInvariant()
// 'T -> string, constrained to the type of its first use
let lowerstring1 = string >> lower
// Same as above
let lowerstring2 value = value |> string |> lower
// Same as above
let lowerstring3 = box >> string >> lower
// 'a -> string, fully generalized
let lowerstring4 value = value |> box |> string |> lower
Я наблюдаю это поведение:
// val token: JToken
// val num: int
let tokstr1 = lowerstring1 token // lowerstring1 now has type JToken -> string
let numstr1 = lowerstring1 num // Error, doesn't compile
(* As above with lowerstring2 and lowerstring3 *)
let tokstr4 = lowerstring4 token // lowerstring4 now has type 'a -> string
let numstr4 = lowerstring4 num // no error, works as 'expected'
I 'Мне непонятно, почему lowerstring3
и lowerstring4
проверяются по-разному.Статические ограничения кажутся вероятными, но если бы это было так, то разве lowerstring4
не удалось бы обобщить?Почему явное присутствие аргумента функции должно иметь значение здесь?