.net - 将标识符模式与 `as` 模式相结合

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

如何将标识符模式的结果复制到 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要采用显式元组,您可以按名称引用它,但另一种方式仍然有效。

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

如果您不想或不能更改您的类型定义,另一种方法是为教师构造函数引入一个事件模式:
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."

关于.net - 将标识符模式与 `as` 模式相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47952179/

相关文章:

functional-programming - 为什么 J 短语 '(2&*~) 15 7 3 1' 会生成一个表,为什么是那个特定的表?

.net - ValueType 包装器的垃圾收集

c# - 将 PictureBox 中的图像转换为位图

c# - 使用函数技术在 F# 中使用泛型重新实现 C# 继承

f# - Seq.groupBy 是否保留组内的顺序?

Linux 上的 F#,没有 .NET 经验

c# - 我需要使用 linq 获取多个索引而不是一个

用于并发编程的 .NET 语言

haskell - F# 中的变质

functional-programming - 静态 "extend"是一种没有间接麻烦的记录数据类型