单例在F#中区分了Union,类型和标签的名称相同

时间:2018-01-10 03:45:30

标签: f# discriminated-union

我在F#文件中有以下代码:

module ORDERS

type OrderId =           // TypeName
    | OrderId of string  // LabelName: same as TypeName!
    with 
    static member getValue (OrderId orderId) =
        orderId

在另一个文件中,我可以使用这样的函数:

// This code works.
module Application
open ORDERS

let x = OrderId "1111"
let extractedValue = 
    x 
    |> OrderId.getValue

但是,如果我尝试删除“打开ORDERS”并用完整路径替换代码,我会收到错误:

// This code fails.
module Application

// This is OK
let x2 = ORDERS.OrderId "11111"

// This has error!
let extractValue2 = 
    x2
    |> ORDERS.OrderId.getValue

我认为原因是在第二个代码中,F#无法区分TypeName“OrderId”和LabelName“OrderId”

问题:

  1. 为什么删除“打开ORDERS”,但指定完整路径会导致代码失败?这两个代码(具有“打开ORDERS”;没有“打开ORDERS”但指定函数的全名)是不是等同于?
  2. 其他问题:

    1. 以不同方式重命名TypeName和LabelName以便它们不会相互冲突会更好吗? e.g。

      module ORDERS
      type OrderIdType =            // TypeName
          | OrderIdLabel of string  // LabelName: different from TypeName!
          with 
          static member getValue (OrderIdLabel orderId) =
              orderId
      
    2. 非常感谢。

1 个答案:

答案 0 :(得分:0)

您可以通过将static方法替换为模块级getOrderIdValue函数来实现如下所示的工作:

module ORDERS =

    type OrderId =           // TypeName
        | OrderId of string  // LabelName: same as TypeName!
        with 
        static member getValue (OrderId orderId) =
            orderId

    let getOrderIdValue (OrderId orderId) =
            orderId

module Application =
    open ORDERS

    let x = OrderId "1111"
    let extractedValue = 
        x 
        |> OrderId.getValue

module ApplicationWithoutOpenOrders =

    // This is OK
    let x2 = ORDERS.OrderId "11111"

    // This has error!
    let extractValue2 = 
        x2
        |> ORDERS.getOrderIdValue