F# дополнительное рекордное поле

Я имею тип записи F# и хочу, чтобы одно из полей было дополнительным:

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 ; 
}

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

let ?t : int = None

но я действительно, может казаться, не заставляю это работать. Тьфу - спасибо

T

13
задан Onorio Catenacci 14 April 2010 в 21:47
поделиться

4 ответа

Как насчет Option?

type tradeLeg = {
    id : int option;
    tradeId : int option;
    legActivity : LegActivityType option;
    actedOn : DateTime option;
    estimates : legComponents option;
    actuals : legComponents option; 
}
6
ответ дан 1 December 2019 в 20:56
поделиться

в качестве комментария к существующим сообщениям, вот пример типа опции:

..
id: int option;
..

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

вы можете скрыть идентификатор с помощью значения опции:

let id = Some 10

или

let id = None

и сослаться на эту страницу MSDN: http: // msdn.microsoft.com/en-us/library/dd233245%28VS.100%29.aspx.

Вот еще один пример типа опции , и вас, вероятно, заинтересует Seq.unfold.

0
ответ дан 1 December 2019 в 20:56
поделиться

Как указывали другие, вы можете использовать тип 'a option . Однако при этом не создается необязательное поле записи (значение которого не нужно указывать при его создании). Например:

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

Чтобы создать значение типа запись , вам все равно нужно указать значение поля 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's not very elegant either):
let defaultRecd = { id = 0; name = ""; flag = None }     
let recd1 = { defaultRecd  with id = 0; name = "" }

К сожалению (насколько мне известно ) вы не можете создать запись, в которой было бы действительно поле опций, которое вы могли бы опустить при ее создании. Однако вы можете использовать тип класса с конструктором, а затем использовать синтаксис ? Fld для создания дополнительных параметров конструктора:

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)

Тип rcd1.Flag будет be bool option , и вы можете работать с ним, используя сопоставление с образцом (как продемонстрировал Инь Чжу). Единственное заметное различие между записями и простыми классами, подобными этому, состоит в том, что вы не можете использовать синтаксис с для клонирования классов и что классы не (автоматически) реализуют семантику структурного сравнения.

22
ответ дан 1 December 2019 в 20:56
поделиться
actuals : legComponents option;
0
ответ дан 1 December 2019 в 20:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: