Ограничения члена F # для кортежей - PullRequest
4 голосов
/ 28 июля 2011

У меня обычно есть момент "о да", пишущий F #, когда я понимаю, что мне нужно где-то дополнительное значение.Как правило, это легко сделать, добавив еще одно значение к передаваемому кортежу.Однако это означает, что различные карты / сортирует / собирает / и т.д.требуется обновление, и, в частности, функции fst / snd работают только с кортежами длины 2.

Это не очень большая проблема, но она достаточно раздражает во время исследовательской разработки, что я бы написал помощника, чтобы облегчитьраздражение:

let inline get2 (t:^a) = (^a : (member get_Item2 : unit -> string) (t, ()))
let inline get2a (t:^a) = (^a : (member Item2 : string) t)

Однако обе версии не работают.Первый, get2, не скомпилируется, с "Ожидается 1 выражение, получено 2".Второй, get2a, будет скомпилирован, но впоследствии не может использоваться для кортежей: «Тип '(int * string)' не поддерживает никаких операторов с именем 'get_Item2'".

Есть ли какие-либоспособ сделать это, что не связано с большим количеством перегрузок? с шумными OverloadID аннотациями (аннотации не требуются в F # 2.0)

Ответы [ 2 ]

8 голосов
/ 28 июля 2011

Причина, по которой ItemX статические ограничения на кортежи F # не работают, заключается в том, что System.Tuple<_,...,_> является только закодированной формой кортежей, а не статическим представлением, используемым компилятором. См. 6.3.2 Tuple Expressions в спецификации.

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

open System
//like get2a but generic return type
let inline get2b (t:^a) = (^a : (member Item2 : 'b) t)

let x = (1,2)
let y = (1,2,3)

get2b (box x :?> Tuple<int,int>)
get2b (box y :?> Tuple<int,int,int>)
3 голосов
/ 28 июля 2011

Вы можете сделать это, используя отражение:

let inline get (t:^a) = t.GetType().GetProperty("Item2").GetValue(t,null) :?> string

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

...