Вопрос

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

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?

Другие идеи?

Это было полезно?

Решение

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

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

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

Представьте, что у Колбинд есть следующая синатура:

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

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

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

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

Концептуально, то, что вы хотите сделать, просто. А System.Data.Datatable Тип уже имеет представление о хранении табличных данных с возможностью динамического добавления столбцов. Но поскольку информация о типе для добавленных столбцов неизвестна во время компиляции, оно следует, что вещи, хранящиеся в этих столбцах, должны рассматриваться как OBJ и отбрасываться во время выполнения.

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top