ID combination with `as` pattern

How to copy the result of the Identifier template into a template to make a tuple?

My question is confusing, so I created an example, I want to print information about a person who is either a teacher or a student:

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

The corresponding pattern is long and repeating:

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

So, I tried to shorten it with a template as, but failed:

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

Because the above teacheris of type Person, not string*int*int list. What to do to have a shorter template without changing the printTeachertype signature string*int*int list -> unit?

+4
source share
1 answer

One way that I can think of is to change the constructor definition 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."
+3

Source: https://habr.com/ru/post/1691268/


All Articles