Инициировать различное объединение разных типов данных с одним конструктором - PullRequest
1 голос
/ 21 марта 2019

скажем, у меня есть такой тип:

type Variedvalue = I of int| S of string | F of float

Есть ли способ создать функцию, которая принимает общий параметр, который инициализирует правильное поле объединения?

то есть что-то вроде

with static member initVariedValue (x : 'a) = 
   match x.getType() with  
   | int -> VariedValue.I x 
   | float -> VariedValue.F x
   | String -> VariedVAlue.S x

Это не работает, даже если я встраиваю его, поскольку общая переменная в этом случае выводится как int, таким образом, никогда не достигнет условного числа с плавающей запятой или строки. Так есть ли какой-нибудь умный способ сделать это, или мне просто нужно создать конструктор для каждого поля?

1 Ответ

0 голосов
/ 25 марта 2019

Да, вы можете сделать это.Однако вам нужно будет поддерживать случай, когда неожиданный тип передается в вашу функцию конструктора.Я бы сделал это, возвращая Result<VariedValue, 'e> вместо прямого VariedValue.В качестве альтернативы вы можете добавить необработанный случай, но это, на мой взгляд, нарушит ожидаемое поведение конструктора.

type VariedValue = I of int| S of string | F of float

module VariedValue =
    let init (x: 'a) =
        match box x with
        | :? int as i -> I i |> Ok
        | :? string as s -> S s |> Ok
        | :? float as f -> F f |> Ok
        | _ -> Error <| sprintf "Unsupported VariedValue Type: %s" (x.GetType().Name)

Примеры:

> VariedValue.init 3;;
[<Struct>]
val it : Result<VariedValue,string> = Ok (I 3)

> VariedValue.init <| System.Guid.NewGuid();;
[<Struct>]
val it : Result<VariedValue,string> =
  Error "Unsupported VariedValue Type: Guid"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...