начал изучать F# сегодня после обеда. похоже, что к концу дня уже и закончил. никакой дополнительной гибкости по сравнению с C# не наблюдается. взять tuples. ок, я могу сматчить первый элемент как (x, _), аналогично head в списке. а как мне сматчить остаток (e.g. tail)? или как итерировать по тупелу заранее неизвестного типа? или как динамически создать тупел, имея, скажем, список типов элементов? а ведь без перечисленного мной ничего осмысленно реляционного не написать. вот у них ничего не пошевелилось в душе, когда они хуярили эти конструкторы?
Tuple(T1)
Tuple(T1, T2)
Tuple(T1, T2, T3)
Tuple(T1, T2, T3, T4)
Tuple(T1, T2, T3, T4, T5)
Tuple(T1, T2, T3, T4, T5, T6)
Tuple(T1, T2, T3, T4, T5, T6, T7)
Tuple(T1, T2, T3, T4, T5, T6, T7, T8)
bonus: Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)
видимо, Билл Гейтс сказал, что 16 параметров должно быть достаточно для любого метода.
Tuple(T1)
Tuple(T1, T2)
Tuple(T1, T2, T3)
Tuple(T1, T2, T3, T4)
Tuple(T1, T2, T3, T4, T5)
Tuple(T1, T2, T3, T4, T5, T6)
Tuple(T1, T2, T3, T4, T5, T6, T7)
Tuple(T1, T2, T3, T4, T5, T6, T7, T8)
bonus: Action(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)
видимо, Билл Гейтс сказал, что 16 параметров должно быть достаточно для любого метода.
(no subject)
Date: 2010-08-20 07:47 am (UTC)и GetValue(i) напиши тоже заодно (см. выше), чтобы два раза не вставать.
(no subject)
Date: 2010-08-20 08:00 am (UTC)Type list - это то же самое, закат солнца вручную - реализация динамической типизации руками поверх языка со статической типизацией.
Во всех попадавшихся мне под руку языках интеграция этого в статическую типизацию или невозможна, или реализуется через метапрограммирование на макросах, или через инфернальный type-level programming типа того же HList. А i там приходится выражать в нумералах чёрча, ага.
Еще один вариант - Reflection
И кстати, насчет GetValue(i) - предлагаю сразу задуматься, какие применения для него? Я пока вижу только как адаптер к нетипизированным вещам вроде DataGrid или типа "вывести тупл целиком в строку".
(no subject)
Date: 2010-08-20 08:19 am (UTC)эээ... вообще-то через него, или его аналог, работает вообще всё что database-related, включая "типизированные" датасеты, таблицы, whatever.
в свою очередь, предлагаю задуматься над причиной появления инфернального HList. значит, есть таки потребность? ну и заодно, что лучше, иметь tuples, которые не tuples, и сбоку прикрученные классы, которые на самом деле позволяют с данными работать, или реализовать один раз нормально?
я не вижу, почему так принципиально трудно сделать нормальную языковую поддержку для операции, например, [int; string] -> int * string - при том что, как ты сам правильно заметил, сделать это через reflection не представляет проблем (unless число элементов в списке типов больше восьми ;).
всё, я пошел спать, глаза слипаются.
(no subject)
Date: 2010-08-20 08:36 am (UTC)Теоретически трудно сделать, да. Т.к это означает все те же compile-time вычисления.
(no subject)
Date: 2010-08-20 09:49 am (UTC)GetValue(i) нужен для одной единственной цели - построить итерацию по таплу для обработки.
По идее, тут достаточно показать человеку как использовать параметрические функции а также map/etc, и проблема уйдёт.
Это в дополнении к:
http://109.livejournal.com/539588.html?thread=2049476#t2049476
(no subject)
Date: 2010-08-20 10:12 am (UTC)Тут помогло бы что-то вроде автоматической генерации подобной функции для любого типа тайпла. Т.е. все тайплы реализуют какой-нибудь интерфейс(typeclass в терминах хаскеля) с методами GetFieldCount GetFieldName(i), GetValue(i) и прочая.
(no subject)
Date: 2010-08-20 10:48 am (UTC)(no subject)
Date: 2010-08-20 11:00 am (UTC)Конвертировать тупл в гетерогенный список типа [SqlInt int;SqlString string], а тип тупла в [Type] и потом по ним итерироваться?
Но функцию конвертации в любом случае без компилятора не сделаешь. И вообще это в дотнете встроенное уже есть, reflection
Вот обратное - из типов и списков сгенерить тупл - уже без метапрограммирования не сделаешь.
(no subject)
Date: 2010-08-21 02:12 am (UTC)wait, так нет же гетерогенных списков.
(no subject)
Date: 2010-08-21 06:19 am (UTC)| SqlInt of int
| SqlString of string
let sqlItems = [SqlInt 1; SqlString "test" ]
Вот. Вполне себе гетерогенный список.
(no subject)
Date: 2010-08-21 02:09 am (UTC)а, ну и ещё - возможно, что это и так есть, просто я не знаю - хотелось бы иметь человеческое инстанцирование из type variable, типа:
class My1 {}
class My2 {}
Type t;
t = My1;
My1 my1 = t.New();// инстанцируем My1
t = My2;
My2 my2 = t.New();// инстанцируем My2
в дельфи было что-то близкое, но я забыл уже. понятно, что через Reflection в дотнете это можно, хочется straightforward syntax.
(no subject)
Date: 2010-08-21 06:18 am (UTC)(no subject)
Date: 2010-08-21 01:52 am (UTC)параметрические функции - это функции с параметрами, да? (что такое параметрические функции в математике я знаю, а что вы тут имели в виду - нет)
(no subject)
Date: 2010-08-21 07:11 am (UTC)Tuple(a) -> (callback a);
Tuple(a,b) -> begin (callback a); (callback b); end;
Tuple(a,b,c) -> begin (callback a); (callback b); (callback c); end;
....
end;
mapTuple you_function your_tuple.
(no subject)
Date: 2010-08-21 07:40 am (UTC)Ну и вообще это закат солнца вручную.
(no subject)
Date: 2010-08-21 08:01 am (UTC)and tuple_2 'a 'b = 'a * 'b
and ...
and callback_argument = tuple_1 | tuple_2 | ....
and calback_result a 'b ... = 'a | 'b | 'c ...;
let callback : callback_argument -> callback_result
(no subject)
Date: 2010-08-20 11:29 pm (UTC)(no subject)
Date: 2010-08-21 06:09 am (UTC)(no subject)
Date: 2010-08-20 09:35 am (UTC)Список имеет тип List A = A * List A | EmptyList.
Список это элемент типа A и ещё точно также список, либо пустой список.
Другими словами, списки гомогенны (содержат элементы одинакового типа данных).
Если же у нас списки гетерогенные - начинается веселуха.
В терминах ООП у нас вводится базовый класс Base и два наследника - A и B
И мы получается список Base'ов... А не список A, B.
В терминах ФЯП это описывается как:
Base = A | B
List Base = Base * List Base | EmptyList;
Теперь приходим к понимаю, что для списка длиной два есть четыре варианта:
A, A
A, B
B, A
B, B
Ну и как это говно типизировать?
Вот и появлются tuple.
Tuple 'a 'b = a' * 'b;
get (a,b) i = match i with
0 -> a
1 -> b
end;
Какой тип результата get?
Естественно, a | b
Теперь проблема понятна?
(no subject)
Date: 2010-08-20 10:02 am (UTC)(no subject)
Date: 2010-08-20 10:47 am (UTC)(no subject)
Date: 2010-08-21 01:28 am (UTC)в F# нет гетерогенных списков.
> Теперь проблема понятна?
она и до того была понятна - в F# нет языковой поддержки для довольно тривиальной вещи, которая мне нужна.
(no subject)
Date: 2010-08-21 06:55 am (UTC)Её нигде нет. Кроме, разве что, Haskell
(no subject)
Date: 2010-08-21 07:06 am (UTC)(no subject)
Date: 2010-08-21 07:11 am (UTC)