Discriminated union member methods

那年仲夏 提交于 2019-12-04 17:53:05

问题


I want to define a method shared by all members of a discriminated union. Currently I've implemented it like this, but it seems really inelegant- surely there is a better way. Suggestions?

type A = 
   {AData:string}
   member this.SharedMethod (x:float) : int= ...
type B =
   {BData:float}
   member this.SharedMethod (x:float) : int= ...
type AB =
| A of A
| B of B

let CallSharedMethod (ab:AB) x =
   match ab with
   | AB.A(a') -> a'.SharedMethod x
   | AB.B(b') -> b'.SharedMethod x

回答1:


What about something like this?

type AB =
    | A of string
    | B of float

    member self.SharedMethod (x : float) =
        match self with
        | A s -> x
        | B f -> f + x

This assumes that you want each variant of your sum type (aka discriminated union) to do something different with the float parameter.

For the case of A, I just return the original value since there's not much else I can do (since there is no generally useful relationship between string and float that yields a float).




回答2:


In your example, you have augmented the record types A and B each with an instance member. However, you can not only augment record types, you can also augment union types (as shown in @Rodrick's answer). If you do this, the union's augmentation will be "shared" by each DU case, which is what you have asked for. To make this more explicit, I have renamed some parts of your example:

type A = { AData:string }
type B = { BData:float }

type AB =
    | ACase of A
    | BCase of B
    member __.SharedMethod x = 0

let callSharedMethod (ab:AB) x = ab.SharedMethod x

If you look at the compiled code in the object browser (or a decompiler like ILSpy), you will see that AB is compiled as the base class of two subclasses AB.ACase and AB.BCase, and SharedMethod belongs to the base class AB.

See also section 8.5.1 of the F# 3.0 specification: Members in Union Types.



来源:https://stackoverflow.com/questions/27136056/discriminated-union-member-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!