2017-12-23 23 views
4

識別子パターンの結果を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を変更せずに、パターンを短くするにはどうすればよいですか?私は考えることができる

答えて

3

一つの方法は、Teacherコンストラクタの定義変更することです:明示的なタプルを取るために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 

を、あなたは名前によってそれを参照することができますが、他の方法はまだ動作します同じように。

タプル項目に名前を付ける機能はなくなりましたが、

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." 

あなたがしたくないか、あなたのタイプの定義を変更できない場合は、別の方法は、教師コンストラクタのアクティブパターンを導入することです

関連する問題