如何将标识符模式的结果复制为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
因为上述teacher
具有Person
类型,而不是string*int*int list
。如何在不更改printTeacher
类型签名string*int*int list -> unit
的情况下缩短模式?
答案 0 :(得分:3)
我能想到的一种方法是改变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."