F#

Aug. 19th, 2010 05:00 pm
109: (Default)
[personal profile] 109
начал изучать 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 параметров должно быть достаточно для любого метода.

(no subject)

Date: 2010-08-20 01:19 am (UTC)
From: [identity profile] sasha-gil.livejournal.com
а как мне сматчить остаток (e.g. tail)?

Вроде паттерны типа first::second::_ (сосиска может быть произвольной длины) должны работать.

По поводу енумирирования по произвольной tuple - это тебе, наверно, захотелось compile-time вычислений ("метапрограммирования" в стиле C++-темплейтов?), такого в F# нет.

(no subject)

Date: 2010-08-20 05:47 am (UTC)
From: [identity profile] thedeemon.livejournal.com
> first::second::_

Это для списков, не для туплов.
109 хочет использовать туплы как гетерогенные списки, а это без выкрутасов не типизируется. Есть ли в F# достаточные выкрутасы - не в курсе.

(no subject)

Date: 2010-08-20 06:46 am (UTC)
From: [identity profile] metaclass.livejournal.com
Отправить его читать Олега про HList и возрадоваться очередной душе, попавшей в цепкие лапы инфернального ФП :)

(no subject)

Date: 2010-08-20 07:36 am (UTC)
From: [identity profile] 109.livejournal.com
> 109 хочет использовать туплы как гетерогенные списки

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

(no subject)

Date: 2010-08-20 09:39 am (UTC)
From: [identity profile] 184467440737095.livejournal.com
тупл это
1) функция, превращающая несколько значений в значение декартового произведения типов
2) функция проекции этого произведения обратно в компоненты

что и написано в документации по приведенной вами ссылке
собственно, самим словом tuple их так позиционировали.


(no subject)

Date: 2010-08-21 01:31 am (UTC)
From: [identity profile] 109.livejournal.com
я знаю, что такое дотнетовский тупл, спасибо. проблема в том, что F# не даёт языковой поддержки для нужных мне операций, хотя мог бы.

(no subject)

Date: 2010-08-20 10:24 am (UTC)
From: [identity profile] permea-kra.livejournal.com
Дык
class SQL_Value 
 = SQL_Bool Bool
 | SQL_SmallInt SmallInt
 ....

type SQL_Row = List < SQL_Value >

уебство, конечно, но обычно плюшки перевешивают бойлерплейт.

(no subject)

Date: 2010-08-21 01:42 am (UTC)
From: [identity profile] 109.livejournal.com
> class SQL_Value
= SQL_Bool Bool
| SQL_SmallInt SmallInt

это на каком языке?

(no subject)

Date: 2010-08-21 07:10 am (UTC)
From: [identity profile] permea-kra.livejournal.com
Это псевдокод. Я не настолько копенгаген, чтобы писать в шарповом синтаксисе.

(no subject)

Date: 2010-08-20 07:33 am (UTC)
From: [identity profile] 109.livejournal.com
ну напиши мне функцию, которая принимает i и возвращает i-й по счёту элемент кортежа.

ну то есть если мы говорим, что F#-ские кортежи хороши для представления датабазных кортежей, то я прошу написать мне SqlDataReader.GetValue(i)

> тебе, наверно, захотелось compile-time вычислений

нет, мне как раз в рантайме надо это делать.

(no subject)

Date: 2010-08-20 07:47 am (UTC)
From: [identity profile] metaclass.livejournal.com
Нет, это как раз compile-time вычисления, т.к. подобная функция стандартными средствами не типизируется.
Собственно говоря, нет проблемы сделать это через Reflection, но это же натягивание совы на глобус и добровольный отказ от преимуществ статической типизации.
SqlDataReader.GetValue(i) и прочий ADO.NET, JDBC, итд - это динамическая типизация.

Чтобы одновременно было и это и статическая типизация - нужна очень хитрая система типов, с инкрементальной типизацией. Она все равно валится будет в рунтайме, если будут ошибки типов, т.е. гарантии валидности будут более слабые, но в отличие от теперешней чисто динамической типизации - валится будет раньше, на этапе prepare запроса (или еще раньше, при подключении к БД), а не на этапе выполнения с обращением к кривому типу и то если результат запроса не пустой.

(no subject)

Date: 2010-08-20 07:54 am (UTC)
From: [identity profile] 109.livejournal.com
перевожу на русский язык: F# не может сделать того, что дельфи могла ещё в прошлом веке, и концепция кортежа (tuple), сделанная в F# first-class citizen, имеет мало отношения к кортежам баз данных, по большому счёту бесполезна, и введена из чисто маркетинговых соображений.

(no subject)

Date: 2010-08-20 08:09 am (UTC)
From: [identity profile] metaclass.livejournal.com
Еще раз: не нужно путать статическую и динамическую типизации.
Дельфи(TDataset, bde и dbexpress и прочая), ADO, ADO.NET, и 90% других базоданновых либ - это все динамическая типизация.
F# tuples, C# class и struct, записи, ADT и прочее - это статическая типизация, со своей достаточно строгой теорией. Tuples в F# введены, т.к. это очевидный элемент оной теории.
Интеграция этого дела возможна, но тянет за собой множество заморочек, которые отражаются в крайней невменяемости большинства ORM-либ. Оные ORM как раз и решают задачу "адаптировать систему типов БД и систему типов языка". Прозрачной интеграции я пока не видел вообще нигде и ни разу, т.к. языки у которых есть нужные для этого фичи, либо сами по себе динамически типизированы, либо в продакшене не используются/


Я лично tuple использую массово чтобы не создавать руками новые типы данных, если мне нужно вернуть два-три значения в результате функции. Если больше - то лучше использовать записи, то бишь те же самые туплы, но вместо порядка полей в них поля именованные.

(no subject)

Date: 2010-08-20 11:28 pm (UTC)
From: [identity profile] 109.livejournal.com
> Еще раз: не нужно путать статическую и динамическую типизации

ещё раз: я не только не путаю, я даже и не употреблял эти термины. ещё раз: эти хуюплы, которые только по недоразумению называют туплами, никак не помогают работать с настоящими туплами, которые в базе данных.

> лучше использовать записи, то бишь те же самые туплы, но вместо порядка полей в них поля именованные

ещё раз: у меня нет в compile-time никакой информации ни о названиях полей, ни о их типах. эта информация приходит из базы в рантайме. тем не менее, ваше предположение о том, что в этом случае типизация невозможна, неверно.

(no subject)

Date: 2010-08-21 06:07 am (UTC)
From: [identity profile] metaclass.livejournal.com
Обычные туплы, тут где-то в комментах уже рассказывали откуда они взяты. То что они не могут быть использованы для работы с БД - это потому что вы их пытаетесь использовать не в тех целях, исходя из похоже названий и теоретической модели лежащей в их основе.

И я про это и пишу: tuple в данном случае сущность времени компиляции, поскольку информации о типах и именах в это время нет - значит его использовать нельзя.
Статическая типизация в этом случае невозможна.

(no subject)

Date: 2010-08-20 09:39 am (UTC)
From: [identity profile] vshabanov.livejournal.com
введена из чисто маркетинговых соображений.

Ржунимагу. Тьюплы -- способ по быстрому сгруппировать небольшие кусочки данных. Используются чтобы вернуть несколько значений из ф-ии (\x -> (x,x*2), вместо out-параметров и объявлений лишних переменных), или для каких-нить сшиваний списков (типа map (\(i,x) -> f i x) $ zip [1..] data).

Т.е. тюплы в ФЯ -- это такое локальное удобство, чтобы не заводить лишних типов-записей.

Если в тюпле больше 2-3 элементов, то это уже плохой стиль (сложно поддерживать) и лучше запись заводить с нормальными именованными полями.

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

Т.е. тюплы -- это не маркетинговый ход, а удобная в ФП (и не только) конструкция.

А если очень надо i-й элемент -- то либо welcome в зависимые типы (которых нет ни в F# ни в Haskell), либо также, как и во всех остальных языках -- динамическая типизация (List/Array.nth i [StringField "asdf", IntField 123, NullField]) и/или навернутый поверх нее маппер в записи и обратно.

F# хоть и убог, но всяко мощнее дельфи и уж точно может сделать то, что что дельфи могла ещё в прошлом веке.

(no subject)

Date: 2010-08-21 01:34 am (UTC)
From: [identity profile] 109.livejournal.com
я и не спорю, что туплы для чего-то другого могут быть полезны. для того, что мне нужно - нет. хотя могли бы.

(no subject)

Date: 2010-08-20 10:03 am (UTC)
From: [identity profile] vshabanov.livejournal.com
А про зависимые типы -- это примерно так:
-- описание типов полей
data FScheme = FString | FInt

-- превращение описания типа поля в тип языка программирования
fType :: FScheme -> Set
fType FString = String
fType FInt    = Int

-- описание типа кортежа -- список типов полей
type TScheme = [FType]

-- превращение описания типа кортежа в тип языка программирования
tType :: TScheme -> Set
tType []     = ()
tType (x:xs) = (x, tType xs)

-- т.е. tType [FString, FInt] выдаст тип кортежа (String, (Int, ())).

-- а вот и i-тый элемент
-- ф-я принимает i, описание типа кортежа, а дальше пошли зависимые типы:
--  * 3-й аргумент имеет тип tType ts -- т.е. тюпл,
--    соответствующий заданной во 2-м параметре схеме
--  * результат -- тип, соответствующий описанию i-го поля из схемы
--
tTypeNth :: (i:Nat) -> (ts:TScheme) -> tType ts -> fType (nth ts i)
tTypeNth O      _        (x, _  ) = x
tTypeNth (S i') (_, ts') (_, xs') = tTypeNth i' ts' xs'

Но так пока можно только в Agda (которая сыровата) или в Coq (который брутален и бессердечен) ну и в еще менее популярных языках.

(no subject)

Date: 2010-08-21 01:40 am (UTC)
From: [identity profile] 109.livejournal.com
> т.е. tType [FString, FInt] выдаст тип кортежа (String, (Int, ()))

ну вот видите, могут же, когда захотят. только нужно (String, Int) получить, а не вложенные туплы, но суть не меняется. а то "невозможно! невозможно!"

(no subject)

Date: 2011-07-10 09:43 pm (UTC)
From: [identity profile] xeno-by.livejournal.com
http://xeno-by.livejournal.com/45951.html?thread=136319#t136319

(no subject)

Date: 2010-08-20 05:44 pm (UTC)
From: [identity profile] alexey-rom.livejournal.com
> концепция кортежа (tuple), сделанная в F# first-class citizen, имеет мало отношения к кортежам баз данных

Естественно. Она имеет отношение к кортежам во всех остальных статически типизированных функциональных языках.

> по большому счёту бесполезна,

Очень полезна (но совсем не для того).

> и введена из чисто маркетинговых соображений.

И унаследована в неизменном виде из языка ML (http://en.wikipedia.org/wiki/ML_%28programming_language%29) 1970-х годов.

(no subject)

Date: 2010-08-20 09:33 am (UTC)
From: [identity profile] 184467440737095.livejournal.com
есть у вас Tuple(T1, T2): (a, b)
вы хотите функцию, (T1, T2)->int -> ??? : f, такую что f(a,b)(1) = T1:a, f(a,b)(2) = T2:b
подозреваю что проверить при компиляции отсутствие ошибок типизации в выражении, содержащем такую функцию, нельзя, поэтому есть две отдельных функции (T1,T2)->T1: f(1) и (T1,T2)->T2: f(2), .Item1 и .Item2 соответвенно.

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

(no subject)

Date: 2010-08-21 01:26 am (UTC)
From: [identity profile] 109.livejournal.com
> то в любом случае с туплами или без них, придется динамически по описанию тупла генерить его тип и потом сами туплы

thank you, Captain Obvious! :) я как бы это и попросил сделать, чуть ли не такими же словами.

Profile

109: (Default)
109

March 2019

S M T W T F S
     12
3456789
101112131415 16
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags