[英]Pretty print discriminated unions
我有一个Option
类型:
type Option<'a> =
| Some of value:'a
| None
type MyString = string
// Syntax
type type-name =
| case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ] type2 ...]
| case-identifier2 [of [ fieldname3 : ] type3 [ * [ fieldname4 : ] type4 ...]
...
我想用这样的格式打印一些东西:
"type-name: case-identifier(fieldname1:type1:'value1', fieldname2:type2:'value2')"
// Example:
let a : Option<MyString> = Some "1"
print a -> "Option: Some(value:MyString:'1')"
let b = None
print b -> "Option: None"
我以前曾问过类似的问题 ,但我仍然无法获得该字段的类型名称和类型。
在您的示例中,您将无法打印MyString
,因为这是一个类型别名,并且类型别名在已编译的代码中没有任何表示形式(仅在一些其他F#元数据中,但这对此没有帮助)。 因此,在编译的代码中,运行时只看到string
。 我将使用单例DU代替:
type Option<'a> =
| Some of value:'a
| None
type MyString =
| MyString of string
override x.ToString() = let (MyString s) = x in s
let a = Some (MyString "1")
let b = None
根据您的示例格式化DU值的函数如下所示:
open Microsoft.FSharp.Reflection
let formatUnion<'T> (value:'T) =
let case, args = FSharpValue.GetUnionFields(value, typeof<'T>)
let args =
[| for f, v in Seq.zip (case.GetFields()) args ->
sprintf "%s:%s='%O'" f.Name f.PropertyType.Name v |]
sprintf "%s: %s(%s)" (typeof<'T>.Name) case.Name (String.concat "," args)
这打印出"Option'1: Some(value:MyString='1')"
- 除了反引号 - 因为类型Option
是通用的,这看起来像你想要的东西 - 我没有做任何聪明的事情处理嵌套类型,这是你还需要添加的一件事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.