Skip to content
Type Providers
step 1/5

Reading — step 1 of 5

Learn

~2 min readAsync, Type Providers, Interop

Type providers are F#'s killer feature: types are generated by code at compile time from external schemas. JSON files, CSV files, SQL databases, REST APIs, OData services — the type provider reads them and gives you typed access without code generation.

JSON Type Provider:

open FSharp.Data

type Repos = JsonProvider<"https://api.github.com/users/dotnet/repos">

let data = Repos.GetSamples()
for repo in data do
    printfn "%s — %d stars" repo.Name repo.StargazersCount

The IDE knows repo.Name and repo.StargazersCount exist because the type provider fetched the URL at compile time, inferred the schema, and generated types. No code generation step. No manual record definitions.

CSV Type Provider:

type Stocks = CsvProvider<"stocks.csv">

let data = Stocks.Load("stocks.csv")
for row in data.Rows do
    printfn "%s closed at %M on %A" row.Symbol row.Close row.Date

The types of row.Symbol, row.Close, row.Date are inferred from the CSV header + sample data. Strings, decimals, dates — all typed.

SQL Type Provider:

open FSharp.Data.Sql

type Sql = SqlDataProvider<
    DatabaseVendor = Common.DatabaseProviderTypes.POSTGRESQL,
    ConnectionString = "Host=localhost;Database=mydb;Username=postgres">

let ctx = Sql.GetDataContext()
let users = query {
    for user in ctx.Public.Users do
    where (user.Active = true)
    select user
}

Schema is read from the live database. Tables, columns, types — all known at compile time. Refactor a column → compile error.

Available providers:

  • JsonProvider — JSON files/URLs
  • CsvProvider — CSV with type inference
  • XmlProvider — XML
  • HtmlProvider — scrape HTML tables
  • SqlDataProvider — multiple DBs
  • OdataProvider — OData services
  • WorldBankProvider — World Bank statistics
  • FreebaseProvider (older) — semantic data
  • Custom providers — ProvidedTypes.fs SDK

Trade-offs:

  • Pro: zero boilerplate, refactor-safe, schema changes caught at compile
  • Con: compile-time URL fetches (caching helps), provider availability (can be flaky), IDE startup slower
  • Con: Generated types live in IDE — sometimes hard to navigate

F# is the only mainstream language with first-class type providers. Use them for data ingestion, scientific computing, anywhere external schemas drive your types.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…