【问题标题】:dot-notation for DUs prevent nestingDU 的点表示法防止嵌套
【发布时间】:2015-02-11 20:54:56
【问题描述】:

使用这两个有区别的工会 (DU):

type Premier = |M1 of int
type Second = |M2 of Premier

我可以拥有这些有效的代码行:

let p_1 = M1 42
let p_2 = 42 |> M1 
let p_3 = Premier.M1 42

let s_1 = M2 (M1 42)
let s_2 = 42 |> M1 |> M2

但不接受以下嵌套 dot 语法(与类语法的重要区别):

let s_3 = Second.M2.M1 42

问题:根本原因是什么?我的意思是与 F# 语法/语法的其他部分是否存在冲突或不一致会阻止它?还是会导致类型推断困难?

跟进:我仍然有 2 种方法(s_1 和 s_2)来定义我的 Second 类型变量,但是对于 DU,是否有更惯用和简洁的第三种方法?

【问题讨论】:

    标签: f#


    【解决方案1】:

    我不明白为什么这应该有效。这两种工作方式是创建包含另一个值的可区分联合的标准方式。从 F# 的角度来看,您尝试的第三个选项没有意义。再解释一下:

    • M1 42Premier 类型的值
    • M2 是一个构造函数,它接受 Premier 并返回 Second
    • M2 (M1 42) 使用参数调用构造函数 - 所以你得到 Second

    使用管道,事情完全一样

    • 42 |> M1int 传递给构造函数 M1 产生 Premier
    • 42 |> M1 |> M2 表示(42 |> M1) |> M2 - 也就是说,它将Premier 值传递给M2 构造函数,然后你得到`Second。

    至于您尝试写Second.M2.M1 42,这是无效的,因为:

    • Second.M2 是一个构造函数(一个函数),它期望 Premier 并返回 Second
    • 函数没有任何成员 - 因此您可以对构造函数执行 .

    【讨论】:

    • 谢谢。对于“Second.M2.M1 42”,我可以想象 Second.M2(作为期望 Premier 的构造函数)理解我为这个 Premier 提供了语法糖“.M1 42”作为“Second.M2”的结尾部分。 M1 42"。当然,它要求函数后面的点接受不属于其成员列表但属于它所引用的子类型成员的后续构造函数。这当然是一个问题。是吗 ?至少,它要求类型推断建立这样一个列表并检查候选者是否有效。 (再次感谢您的明确解释)。 F#中的新手
    • type Second = |M2 of Premier \n\t 静态成员 FM1 (x:int) :Second = M2 (M1 x) \n 然后我可以定义: let s_3 = Second.FM1 42如果我真的想要嵌套 DU 的点表示法。虽然有点令人费解......我当然接受你的回答。
    • @FZed 嗯,我明白你在做什么。使用static member 是最好的方法。问题是,如果你有M3 of Premier * Premier,这不起作用,例如...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    相关资源
    最近更新 更多