热门标签 | 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)
推荐阅读
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细介绍了VMware的多种认证选项,帮助你根据职业需求和个人技能选择最合适的认证路径,涵盖从基础到高级的不同层次认证。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 本文将详细探讨Linux pinctrl子系统的各个关键数据结构,帮助读者深入了解其内部机制。通过分析这些数据结构及其相互关系,我们将进一步理解pinctrl子系统的工作原理和设计思路。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • 本文由杨勇和思远于2012年12月27日撰写,主要探讨了如何使用PHP进行网页内容抓取,特别是针对字符较多的网站。文章详细介绍了正则表达式失效的原因,并提供了优化方法,同时展示了如何抓取淘宝服饰栏、天气信息以及IP地址对应的地理位置。 ... [详细]
  • 探讨如何高效使用FastJSON进行JSON数据解析,特别是从复杂嵌套结构中提取特定字段值的方法。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
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社区 版权所有