0

私がこれを書くことができるような方法で私の型を考案することは可能ですか:

let fieldValues = [nameField, VText "string"; ageField, VInteger 13]

しかし、これではありません: (コンパイル時のエラーになるという意味で):

let fieldValues = [nameField, VInteger 13; ageField, VText "string"]

type value = 
    | VText of string
    | VInteger of int

type ty = 
    | TText
    | TInteger

type field = { Id: int; Type: ty; Name: string }

let nameField = { Id=1; Type=TText; Name="Name" }
let ageField = { Id=2; Type=TInteger; Name="Age" }
4

2 に答える 2

0

やりたいことを正確に行うことは不可能です。ただし、動作する同様のものを次に示します。

type TypedField<'a> = { id : int; name : string }

type FieldConverter<'t> =
    abstract Convert : TypedField<'a> * 'a -> 't

// Necessary only because F# type system won't let you implement FieldConverter<unit>
type FieldFunc =
    abstract Use : TypedField<'a> * 'a -> unit 

type Field =
    abstract ApplyConverter : FieldConverter<'t> -> 't
    abstract ApplyFunc : FieldFunc -> unit

let mkField field value = 
    { new Field with 
        member __.ApplyConverter(f) = f.Convert(field, value) 
        member __.ApplyFunc(f) = f.Use(field, value) }

let nameField : TypedField<string> = { id = 1; name = "Name" }
let ageField : TypedField<int> = { id = 2; name = "Age" }

let fields = [mkField nameField "string"; mkField ageField 13]
// won't compile
let fields' = [mkField nameField 13; mkField ageField "string"]

残念ながら、フィールドを使用するには、かなりの量のボイラープレートが必要です。

// print names and values of all fields
fields
|> List.iter (fun f -> f.ApplyFunc { new FieldFunc with member __.Use(field, value) = printfn "%s: %O" field.name value })
于 2013-09-27T19:54:52.723 に答える