2015-06-02 3 views
2

Я разработал свой домен приложения с пользовательскими типами F #, но теперь кажется, что эти пользовательские типы будут PITA, когда я хочу фактически использовать данные для различных задач ... т.е. записи значений в файл CSV, используя другие библиотеки, которые полагаются на примитивов и т.д.F # cast/convert custom type to primitive

Например, у меня есть пользовательский тип, как это (который используется в качестве строительного блока для других крупных видов):

type CT32 = CT32 of float 

Но код как этот не работает:

let x = CT32(1.2) 
let y = float x //error: The type "CT32" does not support a conversion... 
let z = x.ToString() //writes out the namespace, not the value (1.2) 

Я попытался использовать box/unbox и Convert.ToString() и два оператора F #, но ни один из них не позволяет мне получить доступ к базовому примитивному значению, содержащемуся в моих типах. Есть ли простой способ получить примитивные значения в пользовательских типах, потому что до сих пор они были скорее головной болью, чем действительно полезной.

ответ

1

Ваш type CT32 - это Дискриминационный союз с идентификатором одного случая CT32 of float. Это не alias для типа float, поэтому вы не можете просто бросить его плавать. Чтобы извлечь из него значение, вы можете использовать сопоставление с образцом (это самый простой способ).

type CT32 = CT32 of float 
let x = CT32(1.2) 

let CT32toFloat = function CT32 x -> x 
let y = CT32toFloat x 
let z = y.ToString() 

В качестве альтернативы (если пользовательские типы являются числовыми), вы можете использовать Единицы измерения https://msdn.microsoft.com/en-us/library/dd233243.aspx Они не имеют накладные расходы во время выполнения (я считаю дискриминированные союзы составляются на классы), но обеспечивают безопасность типов во время компиляции.

+0

Спасибо Петр, ты мужчина! Некоторое время назад я учился на учебнике F # по разработке с использованием типов и не совсем понял, как использовать эти одноразовые DU. – Eric

+0

Вы также можете реализовать элемент 'op_Explicit' для использования сопоставления шаблонов для общего' float' cast как @RCH, предложенного ниже – Petr

2

Добавление поддержки float проста:

type CT32 = CT32 of float with 
    static member op_Explicit x = 
     match x with CT32 f -> f 

let x = CT32(1.2) 
let y = float x