F # Свойства доступа высшего порядка - PullRequest
3 голосов
/ 08 июня 2010

Я только что обновил свой кортеж прототипов до рекорда. Когда-нибудь это может стать настоящим классом. А пока я хочу перевести код так:

type Example = int * int
let examples = [(1,2); (3,4); (5,6)]
let descs = Seq.map (fst >> sprintf "%d") examples

к этому:

type Example = {
  Field1 : int
  Field2 : int
  Description : string
}
let examples = [{Field1 = 1; Field2 = 2; Description = "foo"}
                {Field1 = 3; Field2 = 4; Description = "bar"}
                {Field1 = 5; Field2 = 6; Description = "baz"}]
let descs = Seq.map Description examples

Проблема в том, что я ожидал получить функцию Description : Example -> string, когда объявил запись в Примере, но я не получаю. Я немного покопался и попробовал свойства на классах, но это тоже не работает. Я просто что-то упустил в документации или мне придется писать средства доступа более высокого порядка вручную? (Это обходной путь, который я сейчас использую.)

Ответы [ 2 ]

9 голосов
/ 08 июня 2010

Я согласен, было бы неплохо иметь некоторый способ использования экземпляра-члена в качестве значения функции в F # (без явного создания лямбда-функции). На самом деле это обсуждалось несколько раз в сообществе F #. Вот одна ссылка:

Несколько предложенных вариантов из этого обсуждения:

// This would turn '_' automatically into a lambda parameter
// (this looks okay in simple cases, but doesn't probably scale well)
examples |> Seq.map (_.Description)

// You would specify instance member using special '#' symbol
examples |> Seq.map (Example#Description)

Итак, об этом знает команда F #, но я не думаю, что есть какой-то вывод, является ли это действительно важной функцией и как лучше всего ее поддерживать.

0 голосов
/ 08 июня 2010
examples |> Seq.map (fun e -> e.Description)

(Объявление записи не создает никаких связанных функций, но запись имеет свойства, поэтому крошечная лямбда, как указано выше, облегчает проецирование определенных полей.)

...