Reading — step 1 of 5
Learn
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/URLsCsvProvider— CSV with type inferenceXmlProvider— XMLHtmlProvider— scrape HTML tablesSqlDataProvider— multiple DBsOdataProvider— OData servicesWorldBankProvider— World Bank statisticsFreebaseProvider(older) — semantic data- Custom providers —
ProvidedTypes.fsSDK
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…