Короткий ответ - нет, длинный ответ - да (но вам не понравится результат).Главное, что нужно помнить, это то, что F # является языком статической типизации, точка останова .
Для предоставленного вами кода, какой тип имеет 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 # в первую очередь.)
Концептуально, то, что вы хотите сделать, это прямо вперед.Тип System.Data.DataTable уже имеет понятие хранения табличных данных с возможностью динамического добавления столбцов.Но поскольку информация о типе для добавленных столбцов не известна во время компиляции, из этого следует, что вещи, хранящиеся в этих столбцах, должны обрабатываться как Obj и приводиться во время выполнения.