简体   繁体   English

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

[英]Single case Discriminated Union in F#, same name for type and label

I have the following code in an F# file: 我在F#文件中有以下代码:

module ORDERS

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

and in another file, I can utilize the function like this: 在另一个文件中,我可以使用这样的函数:

// This code works.
module Application
open ORDERS

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

However, if I try to remove the "open ORDERS" and replace the code with their full path, I get an error: 但是,如果我尝试删除“打开ORDERS”并用完整路径替换代码,我会收到错误:

// This code fails.
module Application

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

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

I believe the reason is that in the second code, F# cannot differentiate the TypeName "OrderId", and the LabelName "OrderId" 我相信原因是在第二个代码中,F#无法区分TypeName“OrderId”和LabelName“OrderId”

Question: 题:

  1. Why does removing "open ORDERS", but specifying the full path will cause the code to fail? 为什么删除“打开ORDERS”,但指定完整路径会导致代码失败? Aren't the two codes (with "open ORDERS"; without "open ORDERS" but specify full name of functions) equivalent? 这两个代码(具有“打开ORDERS”;没有“打开ORDERS”但指定函数的全名)是不是相同的?

Additional question: 附加问题:

  1. Would it be better to rename the TypeName and LabelName differently so that they won't conflict with each other? 是否更好地重命名TypeName和LabelName,以便它们不会相互冲突? eg 例如

     module ORDERS type OrderIdType = // TypeName | OrderIdLabel of string // LabelName: different from TypeName! with static member getValue (OrderIdLabel orderId) = orderId 

Thank you very much. 非常感谢你。

You could make this work as shown below by replacing the static method with a module-level getOrderIdValue function instead: 您可以通过使用模块级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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM