F#Subtype Disriminated Unions

时间:2015-07-27 11:46:05

标签: f#

我有这样的DU:

type Food =
| Beer
| Bacon
| Apple
| Cherry

我想在DU中添加一个特征来标记食物是否是水果。我首先想到的是这样的事情:

type NonFruit = NonFruit
type Fruit = Fruit

type Food =
| Beer of NonFruit
| Bacon of NonFruit
| Apple of Fruit
| Cherry of Fruit

然后是这样的方法:

让fruitChecker(myFood:Food)=     匹配myFood     | :? NonFruit - > "否"     | :?水果 - > "是"

但是编译器对我大喊大叫:

  

类型'食物'没有任何正确的亚型,不能使用   作为来源

我是否错误地解决了这个问题?

由于

2 个答案:

答案 0 :(得分:9)

或者,使用活动模式:https://msdn.microsoft.com/en-us/library/dd233248.aspx

type Food =
| Beer
| Bacon
| Apple
| Cherry

let (|NonFruit|Fruit|) =
    function
    | Beer | Bacon -> NonFruit
    | Apple | Cherry -> Fruit

let fruitChecker = function | NonFruit -> "No" | Fruit -> "Yes"

[Beer;Bacon;Apple;Cherry] |> List.iter(fun x -> printfn "%s" (fruitChecker x))

打印:

No
No
Yes
Yes

链接:https://dotnetfiddle.net/oRYDs6

答案 1 :(得分:3)

您应该只为其添加一个功能。如果要使其“接近”类型,请将其设为静态成员:

type Food =
   | Beer
   | Bacon
   | Apple
   | Cherry
   static member IsFruit = function Beer | Bacon -> false | Apple | Cherry -> true

将DU案例视为构造函数 - 将啤酒厂的名称传递给Beer构造函数是有意义的,但无论它是否为水果都是静态质量,而不是那里。 / p>