【问题标题】:How to Return Specific Discriminated Union from Function如何从函数返回特定的可区分联合
【发布时间】:2015-07-29 18:06:37
【问题描述】:

我有一个受歧视工会的层次结构。

type SpecificNoun =
    | Noun
    | NounPhrase
    | Pronoun
    | PosesivePronoun

type SpecificModifier =
    | Adverb //slowly, quickly, verb + ly (90% of the time)
    | Preposition //off, on, together, behind, before, between, above, with, below

type SpecificVerb =
    | ActionVerb
    | BeingVerb
    | PossesiveVerb
    | TransitiveVerb

type PartsOfSpeech =
    | Noun of SpecificNoun
    | Verb of SpecificVerb
    | Adjective
    | Punctuation
    | Modifier of SpecificModifier

我需要将一个字符串翻译成其中之一,但它必须是 PartOfSpeech 以便我可以在匹配案例中使用它。以下代码无法编译。

let StringToPartOfSpeech (part:string) =
    match part with
    | "Noun" -> SpecificNoun.Noun
    | "NounPhrase" -> SpecificNoun.NounPhrase
    | "Pronoun" -> SpecificNoun.Pronoun
    | "PossessivePronoun" -> SpecificNoun.PosesivePronoun
    | "Adverb" ->  SpecificModifier.Adverb

这是一个与此相关的问题:F# - Can I return a discriminated union from a function 然而,就我而言,一切都只是直接歧视的工会

【问题讨论】:

  • 我建议更改名称,以便“名词”不会在不同类型中使用两次。阅读起来可能会令人困惑,并且还会混淆类型推断。如果案例名称是唯一的,则不需要 SpecificNoun. 限定符。

标签: f#


【解决方案1】:

您需要从所有分支返回一个 一致 类型。在您的情况下,PartsOfSpeech 类型是理想的。 这意味着您需要采用SpecificNoun.Noun 之类的类型并将其包装在来自PartsOfSpeech 的适当大小写中。

另外,如果输入字符串与任何一种情况都不匹配怎么办?

在下面的代码中,我决定返回一个PartsOfSpeech option,但你可以引发异常, 或返回更详细的成功/失败类型等。

let StringToPartOfSpeech (part:string) =
    match part with
    | "Noun" -> 
        SpecificNoun.Noun |> PartsOfSpeech.Noun |> Some
    | "NounPhrase" -> 
        SpecificNoun.NounPhrase |> PartsOfSpeech.Noun |> Some
    | "Pronoun" -> 
        SpecificNoun.Pronoun |> PartsOfSpeech.Noun |> Some
    | "PossessivePronoun" -> 
        SpecificNoun.PosesivePronoun |> PartsOfSpeech.Noun |> Some
    | "Adverb" ->  
        SpecificModifier.Adverb |> PartsOfSpeech.Modifier |> Some
    | _ ->  None

【讨论】:

    【解决方案2】:

    您的代码无法编译,因为您返回了两个不同类型的值:

    let StringToPartOfSpeech (part:string) =
        match part with
        | "Noun" -> Noun // type of SpecificNoun
        | "NounPhrase" ->NounPhrase  // type of SpecificNoun
        | "Pronoun" -> Pronoun  // type of SpecificNoun
        | "PossessivePronoun" ->PosesivePronoun  // type of SpecificNoun
        | "Adverb" ->  Adverb // type of SpecificModifier
    

    为什么你不使用你的类型 PartsOfSpeech ?

    试试下面的代码:

     type PartsOfSpeech =
            | PNoun of SpecificNoun
            | PVerb of SpecificVerb
            | PAdjective
            | PPunctuation
            | PModifier of SpecificModifier
            | PUnknown
    
    let StringToPartOfSpeech (part:string) =
        match part with
        | "Noun" -> PNoun (Noun)
        | "Adverb" ->  PModifier (Adverb)
        | _ -> PUnknown
    

    另外,为了避免编译器警告,我添加了一个未知字符串的案例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 2020-03-21
      • 2020-02-16
      • 2015-06-30
      • 2017-03-16
      • 1970-01-01
      • 2021-07-20
      相关资源
      最近更新 更多