F # Additional record field

I have an F # record type and want one of the fields to be optional:

type legComponents = {
    shares : int<share> ;
    price : float<dollar / share> ;
    totalInvestment : float<dollar> ;

type tradeLeg = {
    id : int ;
    tradeId : int ;
    legActivity : LegActivityType ;
    actedOn : DateTime ;
    estimates : legComponents ;
    ?actuals : legComponents ; 


in the tradeLeg method I would like the actual field to be optional. I can't seem to figure it out and I can't seem to find a reliable example on the internet. It seems like it should be easy like

let ?t : int = None


but I can't seem to get this to work. Uh - thanks



source to share

4 answers

How about Option


type tradeLeg = {
    id : int option;
    tradeId : int option;
    legActivity : LegActivityType option;
    actedOn : DateTime option;
    estimates : legComponents option;
    actuals : legComponents option; 




As others have pointed out, you can use type 'a option

. However, this does not create an optional record field (which you do not need to supply when creating it). For example:

type record = 
  { id : int 
    name : string
    flag : bool option }


To create a value of a type record

, you still need to provide a field value flag


let recd1 = { id = 0; name = "one"; flag = None }     
let recd2 = { id = 0; name = "one"; flag = Some(true) } 

// You could workaround this by creating a default record 
// value and cloning it (but that not very elegant either):
let defaultRecd = { id = 0; name = ""; flag = None }     
let recd1 = { defaultRecd  with id = 0; name = "" }


Unfortunately (as far as I know) you cannot create a record that actually has a parameter field that you could omit when creating. However, you can use a class type with a constructor, and then you can use the syntax ?fld

to create optional constructor parameters:

type Record(id : int, name : string, ?flag : bool) = 
  member x.ID = id
  member x.Name = name
  member x.Flag = flag

let rcd1 = Record(0, "foo")
let rcd2 = Record(0, "foo", true)


The type rcd1.Flag

will be bool option

, and you can work with it using pattern matching (as Yin Zhu demonstrated). The only noticeable difference between notation and simple classes like this is that you cannot use the syntax with

for cloning classes and that classes do not (automatically) do structural comparison semantics.



actuals : legComponents option;




as a comment on existing posts, here is an example for the option type:

id: int option;

match id with
  | Some x -> printfn "the id is %d" x
  | None -> printfn "id is not available" 


you can block id with the option:

let id = Some 10



let id = None


and go to this MSDN page: http://msdn.microsoft.com/en-us/library/dd233245%28VS.100%29.aspx .

Here 's another example for the type of option, and you are probably interested in Seq.unfold.



All Articles