gpt4 book ai didi

可区分联合的 F# 限制

转载 作者:行者123 更新时间:2023-12-01 06:58:00 24 4
gpt4 key购买 nike

我正在尝试将一个小型编译器从 C# 移植到 F#,以利用模式匹配和可区分联合等功能。目前,我正在使用基于 System.Linq.Expressions 的模式对 AST 进行建模:一个抽象基“表达式”类、每个表达式类型的派生类和一个 NodeType 枚举,允许在不进行大量转换的情况下切换表达式。我曾希望使用 F# 有区别的联合来大大减少这种情况,但我遇到了几个看似限制:

  • 强制公共(public)默认构造函数(我想对表达式构造进行类型检查和参数验证,就像 System.Linq.Expressions 对其静态工厂方法所做的那样)
  • 缺少命名属性(似乎在 F# 3.1 中已修复)
  • 无法直接引用案例类型。例如,似乎我不能声明一个仅从联合中接受一种类型的函数(例如 let f (x : TYPE) = xExpression (联合类型)编译,但不为 AddExpression.Add 编译。这似乎在我的 C# 方法上牺牲一些类型安全。

  • 这些或设计模式是否有很好的解决方法可以让它们不那么令人沮丧?

    最佳答案

    我认为,您对 DU 是类层次结构的想法有点过于执着了。真的,将其视为数据更有帮助。像这样:

    • Forced public default constructor (I'd like to do type-checking and argument validation on expression construction, as System.Linq.Expressions does with it's static factory methods)


    DU 只是数据,很像字符串或数字,而不是功能。为什么不创建一个返回 Expression option 的函数?表示您的数据可能无效。

    • Lack of named properties (seems like this is fixed in F# 3.1)


    如果你觉得你需要命名属性,你可能有一个不合适的类型,比如 string * string * string * int * float作为您的 Expression 的数据.最好做一个记录,比如 AddInfo并让你的 DU 使用它,比如说 | Add of AddInfo .这样你就拥有了模式匹配、智能感知等方面的属性。

    • Inability to refer to a case type directly. For example, it seems like I can't declare a function that takes in only one type from the union (e. g. let f (x : TYPE) = x compiles for Expression (the union type) but not for Add or Expression.Add. This seems to sacrifice some type-safety over my C# approach.


    您不能要求某些东西成为 Add情况,但你绝对可以写一个函数,它需要一个 AddInfo .另外,您始终可以以单子(monad)方式执行此操作,并且具有可以接受任何 Expression 的函数并且只返回 option .在这种情况下,您可以进行模式匹配,即您的输入是适当的类型并返回 None如果不是。在调用站点,您可以使用 Option.bind 之类的函数“使用”好的情况下的值。 .

    基本上尽量不要将 DU 视为一组类,而实际上只是数据的案例。有点像枚举。

    关于可区分联合的 F# 限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19930135/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com