【问题标题】:F# Subtype Discriminated UnionsF# 子类型区分联合
【发布时间】:2015-07-27 11:46:05
【问题描述】:

我有一个这样的 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 与 | :?非水果->“否” | :?水果 -> “是”

但是编译器在骂我:

“食物”类型没有任何适当的子类型,无法使用 作为来源

我是不是错误地处理了这个问题?

谢谢

【问题讨论】:

标签: f#


【解决方案1】:

或者,使用主动模式: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

【讨论】:

    【解决方案2】:

    您应该为此添加一个函数。如果您想让它“接近”类型,请将其设为静态成员:

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

    将 DU 案例视为构造函数 - 将啤酒厂的名称传递给 Beer 构造函数是有意义的,但它是否是水果是一个不合适的静态质量。

    【讨论】:

    • 'match' 关键字需要替换为 'function' 才能编译。
    猜你喜欢
    • 1970-01-01
    • 2020-08-22
    • 2013-08-04
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 2020-05-07
    相关资源
    最近更新 更多