Разбор JSON с использованием Gson для Java

Общий принцип здесь состоит в том, что информация типа течет только «в одну сторону», от внутри до вне выражения. Пример, который вы даете, чрезвычайно прост. Предположим, мы хотели иметь поток информации о типе «в обоих направлениях» при выполнении вывода типа в методе R G(A a) и рассмотреть некоторые из сумасшедших сценариев, которые создают:

N(G(5))

Предположим, что существует десять различных перегрузок N, каждый из которых имеет другой тип аргумента. Должны ли мы сделать десять разных выводов для R? Если бы мы это сделали, мы бы как-то выбрали «лучший»?

double x = b ? G(5) : 123;

. Каким должен быть тип возврата G? Int, потому что другая половина условного выражения является int? Или двойной, потому что в конечном итоге эта вещь будет назначена на двойной? Теперь, возможно, вы начинаете видеть, как это происходит; если вы скажете, что вы рассуждаете извне внутрь, , как далеко вы идете ? Может быть много шагов на этом пути. Посмотрите, что произойдет, когда мы начнем их комбинировать:

N(b ? G(5) : 123)

Теперь что мы будем делать? У нас есть десять перегрузок из N на выбор. Считаем ли мы, что R является int? Это может быть int или любой тип, который int неявно конвертируется в. Но из тех типов, какие из них неявно конвертируются в тип аргумента N? Разве мы пишем себе небольшую прологическую программу и просим движок пролога решить, какие все возможные типы возврата могут быть R, чтобы удовлетворить каждую из возможных перегрузок на N, а затем как-то выбрать лучший?

(Я не шучу, есть языки, которые по существу делают , пишут небольшую прологическую программу, а затем используют логический движок, чтобы определить, что такое все. F # для например, делает более сложный вывод типа, чем C #. Система типов Haskell на самом деле является Turing Complete, вы можете кодировать произвольно сложные проблемы в системе типов и попросить компилятор их решить. Как мы увидим позже, это же верно для разрешение перегрузки в C # - вы не можете кодировать проблему с остановкой в ​​системе типа C #, как вы можете в Haskell, но вы можете кодировать проблемы NP-HARD в проблемы с разрешением перегрузки.)

Это все еще очень простое выражение. Предположим, у вас было что-то вроде

N(N(b ? G(5) * G("hello") : 123));

. Теперь мы должны решить эту проблему несколько раз для G и, возможно, и для N, и мы должны решить их в комбинации . У нас есть пять проблем разрешения перегрузки для решения, и всех из них, если быть справедливым, следует рассматривать как их аргументы, так и их тип контекста. Если для N существует десять возможностей, то для N (N (...)) существует потенциально сотни возможностей и тысяча для N (N (N (...))), и очень быстро вы должны решить проблему проблемы, которые легко имели миллиарды возможных комбинаций и сделали компилятор очень медленным.

Вот почему у нас есть правило, которое вводит информацию только в одном направлении. Он предотвращает такие виды проблем с курицей и яйцами, где вы пытаетесь определить внешний тип из внутреннего типа и определить внутренний тип из внешнего типа и вызвать комбинаторный взрыв возможностей.

Примечание эта информация типа течет в обоих направлениях для лямбда! Если вы скажете N(x=>x.Length), то достаточно уверен, мы рассмотрим все возможные перегрузки N, которые имеют функции или типы выражений в своих аргументах и ​​опробовать все возможные типы для x. И, конечно, есть ситуации, в которых вы можете легко заставить компилятор опробовать миллиарды возможных комбинаций , чтобы найти уникальную комбинацию, которая работает. Правила вывода типа, которые позволяют сделать это для общих методов, чрезвычайно сложны и заставляют даже нервировать Джона Скита. Эта функция делает разрешение перегрузки NP-HARD .

Получение информации о типе в обоих направлениях для лямбда, чтобы общее разрешение перегрузки работало правильно и эффективно занимало меня около года. Это такая сложная функция, которую мы только хотели взять на себя, если бы мы совершенно положительно полюбили бы эту инвестицию. Выполнение работы LINQ стоило того. Но нет соответствующей функции, такой как LINQ, которая оправдывает огромные затраты на выполнение этой работы в целом.

145
задан abhi 10 June 2016 в 14:21
поделиться