Каждый программист иногда обрабатывает много разных форматов данных - это может быть какой-то ответ JSON api, данные SQL или конфигурация XML. А это всегда скучный, рутинный и проблемный процесс. Есть ли хоть один программист, который не допустил опечаток в названиях или типах полей JSON?

Давайте что-нибудь сделаем с ответом StackOverflow API - он возвращает JSON. Например, вывести заголовки последних вопросов. В C # это может выглядеть так:

На самом деле здесь не так много логики, но много шаблонного кода для моделей данных. Конечно, мы можем использовать какой-нибудь язык с динамической проверкой типов - например, Python. И этот код будет намного короче:

Но теперь у нас есть все проблемы с системой динамических типов - например, здесь нам не поможет автодополнение. И, конечно, намного проще сделать опечатку.

Так что нельзя сказать, что это действительно лучше, но, может быть, есть способ совместить преимущества обоих вариантов? Что-то вроде этого:

Здесь мы не пишем никаких моделей данных, но имеем все преимущества проверки статического типа - как вы можете видеть на скриншоте ниже, IntelliSense дает нам полное автозаполнение с правильными именами и типами.

Понимаете? Мы не внедрили никаких моделей данных, но… это работает! Как?

Вся эта магия возможна благодаря механизму языка F #, названному «Поставщики типов». Каждый тип провайдера - это некая библиотека, которая предоставляет функционал для работы с определенным типом. Кстати, мы легко можем заменить одного провайдера другим. Например, если SO API вернет нам XML-ответ, код практически не изменится:

Как работает эта магия? Давайте посмотрим на использование поставщика JSON. При его создании мы передаем пример URL-адреса JSON. JsonProvider извлекает его, определяет его схему и создает соответствующие типы F #. После этого компилятор F # перехватывает созданные типы, и мы можем использовать все преимущества строгой проверки типов, такие как автозаполнение. Теперь можно сопоставить любой JSON с соответствующей схемой с созданными типами.

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

Итак, поставщики шрифтов - это круто. Я покажу вам, насколько это может быть круто на некоторых других примерах.

Не только для чтения

Очевидно, что иногда нам нужно нечто большее, чем просто чтение данных. Хорошим примером является взаимодействие с базой данных SQL - здесь нам понадобятся некоторые другие функции, например, обновление или удаление записей. Было бы не очень хорошо, если бы провайдеры типов не могли выполнять простые операции CRUD… но, конечно, провайдеры типов могут.

SQL Provider может легко выполнять все операции CRUD - это легко сравнить с ORM. Чтобы показать, как это работает, давайте решим простую задачу. Например, заполните поле «IsHoliday» таблицы продаж в соответствии с полем «Дата» с помощью поставщика SQL.

Это действительно похоже на ORM, не так ли? Но мы не создаем никаких моделей данных.

Не только для простых типов данных

Разобрать что-то вроде JSON несложно, но как насчет других источников данных, например HTML? Любой, кто хоть раз разбирал HTML, знает - это необычайно скучная и муторная задача. Так легко сделать глупую ошибку в селекторе!
К счастью, мы можем использовать поставщиков типов, чтобы избежать проблем с синтаксическим анализом HTML. Существует провайдер HTML, который позволяет использовать все преимущества строгой проверки типов при работе с HTML. Давайте воспользуемся им для решения простой жизненной задачи. Недавно мне нужно было получить список глав правительств стран-членов ООН. Попробуем разобрать это из Википедии.

Я даже не смотрел HTML-код Wiki-страницы, HTML-провайдер предоставил мне всю необходимую информацию. И код получился гораздо более читаемым, чем если бы мы использовали для этой цели более распространенные инструменты, такие как HTML Agility Pack.

Не только для данных

Фактически, функциональность поставщиков типов не ограничивается манипуляциями с данными. Есть и другие, гораздо более интересные случаи.
Например, межъязыковая совместимость. Как вы знаете, это может быть непростая задача с множеством подводных камней. Но мы можем сделать это намного проще с помощью поставщиков типов.
Провайдер R прекрасно это показывает. Как вы можете догадаться, это позволяет использовать возможности R из F #. Давайте посмотрим на пример использования из документации R Provider.

Как видите, этот поставщик типов позволяет использовать функции другого языка в качестве некоторых библиотек NuGet. Кстати, этот пример показывает, как несколько поставщиков типов могут использоваться вместе.

Заключение

Итак, поставщики типов могут помочь вам написать очень эффективный и надежный код. Конечно, я не показал все возможные варианты использования провайдеров типов - они действительно безграничны. Существуют поставщики типов для взаимодействия с JavaScript, Swagger и многим другим. И ничто не мешает создать свой поставщик шрифтов - отличные рекомендации по этому поводу можно найти в блоге Сергея Тихона.