Могу ли я сделать запись более гибкой? - PullRequest
1 голос
/ 11 марта 2011

Может кто-нибудь привести пример того, как сделать вставку данных в запись F # более гибкой?

Я часто вижу примеры использования таких записей:

type Employee = {mutable name:string; mutable id:string}

let data = 
    [{name = "Thomas";id = "000"};
     {name = "Johny";id = "001"};
     {name = "Lucky";id = "002"};
     {name = "Don";id = "003"}
    ]

Разве мы не можем начать вообще без данных и вставить данные в запись позже?

(я имею в виду без объявления значения данных, как в примере, например: программа работает и запрашивает вставку данных)

Можем ли мы сделать что-то подобное с записью?

Ответы [ 2 ]

4 голосов
/ 11 марта 2011

Если вы говорите об указании значений записи по мере того, как они становятся доступными, то вам нужно сделать поля записи option, чтобы вы могли представить факт, что значение отсутствует.Я буду использовать неизменяемые записи, потому что это чаще встречается в функциональном стиле:

type Employee = { Name:option<string>; ID:option<string> }  

Теперь вы можете создать запись только с идентификатором и добавить имя, когда пользователь вводит ее:

let empty = { Name = None; ID = Some 123 }
let name = // read name from user
let full = { empty with Name = name }

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

let rec readData i records = 
  let name = // read name from user 
  if name <> "" then
    // Create new record and add it to our list
    let itm = { Name = name; ID = string i }
    readData (i + 1) (itm::records)
  else 
    // Return records that we collected so far in the right order
    records |> List.rev

В качестве альтернативы вы также можете использовать выражения последовательности (см., Например, free Глава 12 (PDF) реального функционального программирования).Если ваше взаимодействие с пользователем предполагает ожидание событий (например, щелчок мышью), тогда вы все равно можете использовать этот стиль, но вам нужно обернуть все в асинхронный рабочий процесс и использовать Async.AwaitEvent.

1 голос
/ 11 марта 2011

Вы видели, как вы часто видели такой пример?

Я бы сказал, что в F # не очень идиоматично использовать изменяемые записи.

Неизменность довольно большой предмет объяснить в одном ответе здесь, но вкратце: неизменность означает, что объекты, которые вы создаете никогда не меняются : они остаются такими, какими были создание. В неизменном мире, когда Вы хотите «изменить» что-то, вы создать новый и выбросить старый.

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

let data = []
let data = {name = "Thomas";id = "000"} :: data
let data = {{name = "Johny";id = "001"} :: data

Но в этом случае вы на самом деле не «меняете» данные, вы просто каждый раз создаете новый список и указываете на него данные.

...