1

Can somebody give me an example of how to make inserting data into an F# record more flexible?

I often see examples using records like this:

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"}
    ]

Can't we start with no data at all and insert the data into the record later?

(What I mean is without declaration of the value of the data like in the example, so for example: the program is running and asking us to insert the data)

Can we doing something like this with record?

Benjol
  • 63,995
  • 54
  • 186
  • 268
alex_nan
  • 13
  • 2

2 Answers2

4

If you're talking about specifying values of a record as they become available, then you need to make fields of the record option so that you can represent the fact that value is missing. I'll use immutable records, because this is more common in functional style:

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

Now you can create a record with only ID and add name when the user enters it:

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

If you're talking about adding items to a list as they become available, then you have several options. The direct one is to write a recursive function that repeatedly reads record and builds a list:

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

Alternatively, you can also use sequence expressions (see for example free Chapter 12 (PDF) of Real-World Functional Programming). If you user interaction involves waiting for events (e.g. mouse click), then you can still use this style, but you'd need to wrap everything in asynchronous workflow and use Async.AwaitEvent.

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • hello sir, thank you very much for your answer. Can you help me again? I'm still a newbie in F#. If using your code, that mean the name value should be Some string, is that correct? and can you give me advice sir? how to learn this language, because i trying to learn by write the example from book or else but when i want to write some application, i ended with code like i do with imperative language, then finally i ended with confusion about the concept of this language. I kind of frustated here :) – alex_nan Mar 13 '11 at 05:51
1

Are you saw you often saw an example like that?

I'd say that it is not very idiomatic in F# to use mutable records.

Immutability is a rather large subject to explain in one answer here, but briefly: immutability means that the objects you create never change: they stay the way they were at creation. In the immutable world, when you want to 'change' something, you create a new one, and throw away the old one.

Anyway, if I understand your question correctly, you are actually talking about mutating data, not the record. So, you could have:

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

But in this case, you aren't really 'changing' data, you are just creating a new list each time and pointing data at it.

Community
  • 1
  • 1
Benjol
  • 63,995
  • 54
  • 186
  • 268
  • thank you, yes i already knew that using your code it doesn't changing the data. I just want to write simple application like i write in C++, store the data, delete the data, search the data, and look the data. In C++ i was using array, it's pretty easy.. i just try to make this simple application using record..but i found it hard – alex_nan Mar 13 '11 at 06:00