Как добавить симпатичный принтер для универсального типа в fsi?
В F# Interactive (FSI), вы можете использовать AddPrinter
или же AddPrinterTransformer
обеспечить красивую печать для типа в интерактивной сессии. Как я могу добавить такой принтер для универсального типа? Использование подстановочного знака _
для типа не работает:
> fsi.AddPrinter(fun (A : MyList<_>) -> A.ToString());;
Принтер просто не используется.
Ввод параметра типа также дает предупреждение:
> fsi.AddPrinter(fun (A : MyList<'T>) -> A.ToString());;
fsi.AddPrinter(fun (A : MyList<'T>) -> A.ToString());;
-------------------------------^^
d:\projects\stdin(70,51): warning FS0064: This construct causes code
to be less generic than indicated by the type annotations. The type
variable 'T been constrained to be type 'obj'.
чего я тоже не хочу
1 ответ
Это не сработает для общего случая, но, поскольку кажется, что вы работаете со своим собственным типом (по крайней мере, в вашем примере) и предполагаете, что не хотите влиять ToString
Вы могли бы сделать что-то вроде этого:
type ITransformable =
abstract member BoxedValue : obj
type MyList<'T>(values: seq<'T>) =
interface ITransformable with
member x.BoxedValue = box values
fsi.AddPrintTransformer(fun (x:obj) ->
match x with
| :? ITransformable as t -> t.BoxedValue
| _ -> null)
Выход:
> MyList([1;2;3])
val it : MyList<int> = [1; 2; 3]
Для стороннего универсального типа вы можете использовать AddPrintTransformer
и отражение, чтобы получить значение для отображения. Интерфейс становится проще, если у вас есть источник.