开发者

Match on discriminated union

开发者 https://www.devze.com 2023-02-12 22:29 出处:网络
Using F# for the first time for a production thing and need a little help. Please see this code where I added the warnings I get as comments on each line:

Using F# for the first time for a production thing and need a little help. Please see this code where I added the warnings I get as comments on each line:

type AssetClass = 
    | Corp
    | Corp_SME
    | Res_Mort
    | Qual_Ret
    | Ret_Oth

let Correlation assetClass pd sales = 
    match assetClass with 
    | Corp -> 0.12 
    | CORP_SME -> 0.24 // warning FS0049: Uppercase variable identifiers
    | Res_Mort -> 0.15 // warning FS0026: This rule will never be matched
    | Qual_Ret -> 0.04 // warning FS0026: This rule will never be matched
    | Ret_Oth  -> 0.03 // warning FS0026: This rule will never be matched

I checked and it's not bluffing, the third and other cases really are ignored. What am I not getting here? (The pd and sales inputs I do use in the real implementation, I just left out the formulas here.)

What I want to do is use the discriminated union as I would use an enum in C#, and then switch on it. So in C# I would have typed this:

    enum AssetClass {
        Corp,
        Corp_SME,
        Ret_Oth
    }

    float Correlation(AssetClass assetClass){
        switch(assetClass){
            cas开发者_如何学Ce Corp: return 0.12; 
            case Corp_SME: return 0.12;
            case Ret_Oth: return 0.12; 
        }
    }

Could someone help me out?

Thanks in advance,

Gert-Jan


You called your constructor Corp_SME but try to match it with CORP_SME (all caps). Since this is not the name of any constructor, F# assumes it's a variable name (thus the warning about upper case variable names), which then of course matches everything not previously matched (thus the subsequent warnings).


As a side-note, you can also declare enum types in F#. To do that, you just add some integer values to the cases of the type:

type AssetClass = 
    | Corp = 0
    | Corp_SME = 1
    | Res_Mort = 2
    | Qual_Ret = 3 
    | Ret_Oth = 4

To use the enum in pattern matching, you then have to use fully qualified name, so you cannot accidentally get the issue you got - you have to write | AssetClass.Corp -> ...

You can also get this behavior for usual discriminated unions if you annotate the type with [<RequireQualifiedAccess>] attribute. This is probably a good idea as you're not polluting the namespace (but I use it only when I have too many DUs or some conflicting names).

0

精彩评论

暂无评论...
验证码 换一张
取 消