【问题标题】:Idioms/Practices for Implementing Constrained Numeric Types in F#?在 F# 中实现约束数值类型的习惯用法/实践?
【发布时间】:2016-04-22 03:43:14
【问题描述】:

假设需要一种数值数据类型,其允许值在指定范围内。更具体地说,假设要定义一个整数类型,其最小值为 0,最大值为 5000。这种情况出现在很多情况下,例如在建模数据库数据类型、XSD 数据类型等时。

在 F# 中为这种类型建模的最佳方法是什么?在 C# 中,执行此操作的一种方法是定义一个结构,该结构实现范围检查重载运算符、格式设置等。此处描述了 F# 中的类似方法:http://tomasp.net/blog/fsharp-custom-numeric.aspx/

我真的不需要成熟的自定义类型;我真正想要的是具有受限域的现有类型。例如,我希望能够写出类似

的东西
type MyInt = Value of uint16 where Value <= 5000 (pseudocode)

是否有在 F# 中执行此类操作的速记方法,或者是实现上述博客文章中描述的自定义数字类型的最佳方法?

【问题讨论】:

  • 如果您正在寻找成熟的值相关类型,您可以查看F*

标签: f# refinement-type


【解决方案1】:

您指的是类型论中所谓的细化类型,正如 Daniel 指出的那样,请查找 F*。但这是一个研究项目。

至于使用 F# 进行操作,除了 Tomas 的帖子,请查看 designing with types 系列。

【讨论】:

    【解决方案2】:

    我的建议是实现一个自定义结构来包装您的数据类型(例如,int),就像在 C# 中一样。

    创建此自定义结构背后的想法是,它允许您在运行时“拦截”底层数据值的所有使用情况并检查它们的正确性。另一种方法是在编译时检查所有这些用途,这可以使用 F* 之类的东西(正如其他人提到的那样),尽管它要困难得多,而且你不会在日常代码中使用它。

    【讨论】:

    • 结构体有一个允许绕过验证的默认构造函数,这将如何工作?
    • 结构的其他成员——例如,自定义操作符——也应该验证结构。所以如果你使用结构体的默认值,你不会立即知道它是无效的,但你会在第一次使用该值时发现。
    • 这似乎很奇怪,因为定义类型的目的是确保对数据的某些保证。
    • 也许是这样,但有时你必须在实践中做出妥协。使用这种技术,您仍然可以获得这些保证——妥协是您可能不会立即知道何时违反了类型的不变量。我发现只要你在开始编写代码时就知道存在这种可能性,我会格外小心地确保没有默认值可以进入核心代码。
    猜你喜欢
    • 2016-11-16
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2011-04-30
    • 2018-06-23
    相关资源
    最近更新 更多