热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

F#Interactive中的数据格式化技巧:使用AddPrinter和AddPrintTransformer自定义输出

本文探讨了如何在F#Interactive(FSI)中通过AddPrinter和AddPrintTransformer方法自定义类型(尤其是集合类型)的输出格式,提供了详细的指南和示例代码。
在 F# 编程中,有时我们需要改变某些类型在 FSI 中的默认输出格式,特别是对于集合类型。本文将介绍几种方法来实现这一目标,并提供具体的代码示例。

### 使用 AddPrintTransformer 和 AddPrinter

一个简单的方法是使用 `fsi.AddPrintTransformer` 来生成对象的替代显示形式,或者使用更小的 `fsi.AddPrinter` 函数直接生成字符串表示。例如:

```fsharp
type C(elems: int list) =
member x.COntents= elems
member x.IsBig = elems.Length > 100

let c = C [1; 2; 3]
fsi.AddPrintTransformer (fun (c:C) -> box c.Contents)
```

这会使得 `c` 的输出为 `[1; 2; 3]`。

`AddPrintTransformer` 的优点是可以根据条件返回 `null` 来忽略格式化器,例如:

```fsharp
fsi.AddPrintTransformer (fun (c:C) -> if c.IsBig then null else box c.Contents)
```

此外,你还可以对任意对象进行特定格式化:

```fsharp
fsi.AddPrintTransformer (fun (obj: obj) -> match obj with :? C as c -> box c.Contents | _ -> null)
```

### 使用 StructuredFormatDisplayAttribute

如果你希望更改 `sprintf`、`printf` 等函数中的 `%A` 行为,可以使用 `StructuredFormatDisplayAttribute` 属性。例如:

```fsharp
[]
type C(elems: int list) =
member x.COntents= elems

let c = C [1; 2; 3]
```

这会使得 `c` 的输出为 `CCC [1; 2; 3]`。

### 针对不同类型的最佳实践

- **普通集合类**:使用列表或序列作为替代对象。
- **矩阵或表格类型**:使用二维数组作为替代对象。
- **联合类型**:考虑使用辅助联合类型来解开抽象边界。
- **递归树型数据**:描述子树为列表。

例如,对于递归树型数据:

```fsharp
[]
type Tree(node: int, elems: Tree list) =
member x.COntents= (node, elems)

let c = Tree(1, [Tree(2, []); Tree(3, [Tree(4, [])])])
let c2 = Tree(1, [c; c])
let c3 = Tree(1, [c2; c2])
```

### 其他建议

为了提高调试体验,还应考虑实现 `ToString` 方法,并为 VS 调试器添加 `DebuggerDisplay` 属性。

参考资料:
- [DSyme 博客](http://blogs.msdn.com/b/dsyme/archive/2010/01/08/some-tips-and-tricks-for-formatting-data-in-f-interactive-and-a-in-sprintf-printf-fprintf.aspx)
- [CNBlog 文章](https://www.cnblogs.com/tryfsharp/archive/2011/12/31/2308486.html)
推荐阅读
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • 本文详细介绍了VMware的多种认证选项,帮助你根据职业需求和个人技能选择最合适的认证路径,涵盖从基础到高级的不同层次认证。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 华为USG基于源地址的多出口策略路由配置
    网络拓扑如下:组网情况:企业用户主要有技术部(VLAN10)和行政部(VLAN20),通过汇聚交换机连接到USG。企业分别通过两个不同运营商(ISP1和ISP2)连接到 ... [详细]
author-avatar
手机用户2502933677
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有