【问题标题】:Combine Identifier pattern with `as` pattern将标识符模式与 `as` 模式结合起来
【发布时间】:2018-06-05 17:42:01
【问题描述】:

如何将标识符模式的结果复制到 as 模式以制作元组?

我的问题很困惑,所以我创建了一个例子,我想打印这个人的信息,无论是老师还是学生:

type Person =
    | Teacher of name: string * age: int * classIds: int list
    | Student of name: string

let printTeacher (name, age, classIds) =
    printfn "Teacher: %s; Age: %d; Classes: %A" name age classIds

let print = function
    | Teacher (name, age, classIds) -> printTeacher (name, age, classIds)
    | Student name -> printfn "Student: %s" name

匹配模式长且重复:

| Teacher (name, age, classIds) -> printTeacher (name, age, classIds)

所以我尝试使用as 模式使其更短,但失败了:

| Teacher ((_, _, _) as teacher) -> printTeacher teacher

因为上面的teacherPerson 类型,而不是string*int*int list。在不更改printTeacher 类型签名string*int*int list -> unit 的情况下,我应该怎么做才能获得更短的模式?

【问题讨论】:

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


    【解决方案1】:

    我能想到的一种方法是更改​​ Teacher 构造函数的定义:

    type Person =
        | Teacher of items: (string * int * int list)
        | Student of name: string
    
    let printTeacher (name, age, classIds) =
        printfn "Teacher: %s; Age: %d; Classes: %A" name age classIds
    
    let print = function
        //| Teacher (name, age, classIds) -> printTeacher (name, age, classIds) // Still works
        | Teacher items -> printTeacher items
        | Student name -> printfn "Student: %s" name
    

    通过更改 Teacher 以获取显式元组,您可以通过名称引用它,但其他方式仍然有效。

    但是,您失去了为元组项命名的功能。

    如果您不想或不能更改类型定义,另一种方法是为 Teacher 构造函数引入活动模式:

    type Person =
        | Teacher of name: string * age: int * classIds: int list
        | Student of name: string
    
    // Active pattern to extract Teacher constructor into a 3-tuple.
    let (|TeacherTuple|_|) = function
    | Teacher (name, age, classIds) -> Some (name, age, classIds)
    | _ -> None
    
    let printTeacher (name, age, classIds) =
        printfn "Teacher: %s; Age: %d; Classes: %A" name age classIds
    
    let print = function
        | TeacherTuple items -> printTeacher items
        | Student name -> printfn "Student: %s" name
        // To make the compiler happy. It doesn't know that the pattern matches all Teachers.
        | _ -> failwith "Unreachable."
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-20
      • 1970-01-01
      • 2016-11-07
      • 2011-10-04
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多