Поставщики типов F# и обработка данных

в предыдущем вопросе (работа с гетерогенными данными на статически типизированном языке), Я спросил о том, как F# обрабатывает стандартные задачи в анализе данных, такие как управление нетипизированным CSV-файлом. Динамические langauges преуспеть в основных задачах, таких как

data = load('income.csv')
data.log_income = log(income)

В F# самым элегантным подходом, по-видимому, является знак вопроса (?) оператор. К сожалению, в процессе мы теряем статическую типизацию и все еще нуждаемся в аннотациях типа здесь и там.

один из самая захватывающая будущая функция F# -Операторы Типа. С минимальной потерей безопасности типов поставщик типов CSV может предоставлять типы путем динамического изучения файла.

но анализ данных обычно на этом не останавливается. Мы часто преобразуем данные и создаем новые наборы данных через конвейер операций. Мой вопрос в том, могут ли поставщики типов помочь, если мы в основном манипулируем данными? Например:

open CSV // Type provider
let data = CSV(file='income.csv') // Type provider magic (syntax?)
let log_income = log(data.income) // works!

это работает, но засоряет глобальное пространство имен. Это часто более естественно думать о добавлении столбца, а не о создании новой переменной. Есть ли какой-то способ сделать это?

let data.logIncome = log(data.income) // won't work, sadly.

обеспечивают ли поставщики типов побег от использования (?) оператор, когда целью является создание новых производных или очищенных наборов данных?

возможно, что-то вроде:

let newdata = colBind data {logIncome = log(data.income)}  // ugly, does it work?

другие идеи?

2 ответов


короткий ответ-нет, ответ-да (но вам не понравится результат). Главное, что нужно помнить, - это то, что F# - статически типизированный язык, full stop.

для кода, который вы предоставили, какой тип имеет newData? Если он не может быть закреплен во время компиляции, вам нужно прибегнуть к кастингу в/из Obj.

// newdata MUST have a static type, even if obj
let newdata = colBind data {logIncome = log(data.income)}  

представьте, что colBind имеет следующую синатуру:

val colBind: Thingey<'a> -> 'b -> Thingey2<'a, 'b>

это действительно сработает для способов, но это не будет работать повсеместно. Потому что в конечном итоге вам понадобится тип, который не будет существовать во время компиляции.

поставщики типов F# позволяют статически типа данные, исходящие из-за пределов стандартной среды времени компиляции. Однако типы по-прежнему статичны. Невозможно динамически изменять эти типы во время выполнения*.

*вы можете изменить объект во время выполнения, используя такие махинации, как DynamicObject. Однако, однажды ты ... начинай идти по пути, который ты теряешь. все преимущества статически типизированного язык, такой как Intellisense. (Что является основной причиной использования F# в первую очередь.)

концептуально, что вы хотите сделать это прямо вперед. The


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