将标识符模式与“as”模式相结合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将标识符模式与“as”模式相结合相关的知识,希望对你有一定的参考价值。

如何将标识符模式的结果复制为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,我应该怎样做才能拥有更短的模式?

答案

我能想到的一种方法是改变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."

以上是关于将标识符模式与“as”模式相结合的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ:第一章:6 种工作模式以及消息确认机制(理论与代码相结合)

二万字长文图文详解RabbitMQ6 种工作模式(理论与代码相结合)

Java 设计模式——单例模式 理论代码相结合

专访Latif Ladid教授|以IPv6与区块链相结合的模式来应对供应链的低效问题

专访Latif Ladid教授|以IPv6与区块链相结合的模式来应对供应链的低效问题

如何将 log4j 每日日志轮换与基于文件大小的轮换和最大备份相结合?