【问题标题】:Downcast union cases without warning errors没有警告错误的沮丧工会案例
【发布时间】:2018-06-09 17:54:42
【问题描述】:

如何让编译器忽略一些向下转换的模式匹配警告 (FS0025) 但必须在同一文件中捕获其他 FS0025 警告?

例如,第一个模式匹配 (Student studentName) = john 永远不会抛出错误,所以我希望编译器删除不必要的警告。

type Job = Student of string | Teacher of string

let john = Student "John"

(* FS0025: Incomplete pattern matches on this expression. For example,
the value 'Teacher _' may indicate a case not covered by the pattern(s). *)
let (Student studentName) = john
let (Teacher teacherName) = john // runtime error

我试过了:

#nowarn "25"
let (Student studentName) = john
#warn "25"
let (Teacher teacherName) = john

但它没有显示let (Teacher teacherName) = john 的任何警告错误。

【问题讨论】:

    标签: .net f# functional-programming pattern-matching


    【解决方案1】:

    如果您愿意使用 GADT 在类型中记录使用的构造函数,您可以编写类似这样的内容(OCaml 语法,我没有安装 F#):

    type student
    type teacher
    
    type _ job =
      | Student : string -> student job
      | Teacher : string -> teacher job
    
    let john = Student "John"
    

    然后您的第一个模式匹配被接受而不发出警告(它是全部:只有一个构造函数用于student job 类型的值):

    let (Student studentName) = john
    

    第二个在类型检查时被拒绝,因为studentteacher 不相等:

    let (Teacher teacherName) = john
    

    您可以通过编写来自'a job 的函数来编写涵盖所有jobs 的函数。

    【讨论】:

    • 这是一个很好的解决方案,遗憾的是 F# 不支持 GADT。
    【解决方案2】:

    在这个特定的示例中,两种情况都有相同的数据,一个名称字符串,因此您可以通过模式匹配来获取名称:

    let name = match john with Student n | Teacher n -> n
    

    如果要多次添加,可以将其添加为类型的成员:

    type Job =
        | Student of string
        | Teacher of string
        member this.Name = match this with Student n | Teacher n -> n
    
    let john = Student "John"
    let name = john.Name
    

    【讨论】:

      【解决方案3】:

      如果无法访问 GADT,您必须以附加包装器类型的形式添加一些额外的样板:

      type Student = Student of string 
      type Teacher = Teacher of string
      
      type Job = StudentJob of Student | TeacherJob of Teacher
      
      let john = Student "John"
      
      let (Student studentName) = john // no warning
      let (Teacher teacherName) = john // compile error
      

      【讨论】:

        猜你喜欢
        • 2015-01-22
        • 1970-01-01
        • 2011-04-03
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多