2016-08-30 30 views
5

Tôi có một câu hỏi có thể khác thường, nhưng cách có khớp với hàm trong F # bằng cách sử dụng đối sánh mẫu không?Mẫu khớp với hàm trong F #

Hãy tưởng tượng như sau:
Tôi có nhiều chữ ký chức năng, mà sẽ được sử dụng nhiều lần, như:

binary function: int -> int -> int 
unary function: int -> int 
boolean function: int -> int -> bool 
... 

Bây giờ tưởng tượng chức năng evaluate, mà tự nó có một chức năng f. Chữ ký của fphải là một trong những danh sách được liệt kê ở trên. Làm cách nào để khớp với một trường hợp như vậy?


Tôi đã thử những điều sau đây:
Kiểm tra số 1: Sử dụng đại biểu và đoàn:

type UnaryFunction = delegate of int -> int 
type BinaryFunction = delegate of (int -> int) -> int 
type BooleanFunction = delegate of (int -> int) -> bool 

type Functions = 
    | Unary of UnaryFunction 
    | Binary of BinaryFunction 
    | Boolean of BooleanFunction 

// ... 

let evaluate f = // signature: Functions -> string 
    match f with 
    | Unary u -> 
     let test_result = u.Invoke 3 
     sprintf "the result of the unary function is %d" test_result 
    | Binary b -> 
     let test_result = b.Invoke 315 42 
     sprintf "the result of the binary function is %d" test_result 
    | Boolean o -> 
     let test_result = o.Invoke 315 42 
     if test_result then "yeah" else "nope" 

Kiểm tra số 2: Sử dụng loại khớp mẫu và các đại biểu:

type UnaryFunction = delegate of int -> int 
type BinaryFunction = delegate of (int -> int) -> int 
type BooleanFunction = delegate of (int -> int) -> bool 

let evaluate f = 
    match f with 
    | ?: UnaryFunction as u -> 
     let test_result = u.Invoke 3 
     sprintf "the result of the unary function is %d" test_result 
    | ?: BinaryFunction as b -> 
     let test_result = b.Invoke 315 42 
     sprintf "the result of the binary function is %d" test_result 
    | ?: BooleanFunction as o -> 
     let test_result = o.Invoke 315 42 
     if test_result then "yeah" else "nope" 
    | _ -> "invalid function type" 


Vấn đề với các ví dụ này là, đại biểu của ... sẽ được đối sánh thay vì các chức năng thực tế. Tôi muốn xem somethink như thế này:

let evaluate f = 
    match f with 
    | ?: (int -> int) as u -> 
     let test_result = u 3 
     sprintf "the result of the unary function is %d" test_result 
    | ?: ((int -> int) -> int) as b -> 
     let test_result = b 315 42 
     sprintf "the result of the binary function is %d" test_result 
    | ?: ((int -> int) -> bool) as o -> 
     let test_result = o 315 42 
     if test_result then "yeah" else "nope" 
    | _ -> "invalid function type" 

F # có cú pháp đặc biệt cho khớp mẫu không?
Và nếu không, tại sao vậy? Tôi có thiếu thứ gì đó hay không cũng quan trọng để có thể kết hợp các chức năng giống như bất cứ điều gì khác, vì đây là ngôn ngữ chức năng?

+4

Tại sao bạn cần sử dụng đại biểu thay vì chức năng? –

+0

@FyodorSoikin: Tôi đã thử nó trước đây, nhưng do một lỗi đánh máy (mà tôi đã không nhận ra tại thời điểm đó), tôi không thể định nghĩa các loại như chức năng. Do đó tôi nghĩ rằng nó là không thể:/ – Unknown6656

Trả lời

10

Thay vì sử dụng các đại biểu, chỉ cần xác định công việc bằng cách sử dụng chức năng trực tiếp:

type UnaryFunction = int -> int 
type BinaryFunction = int -> int -> int 
type BooleanFunction = int -> int -> bool 

type Functions = 
    | Unary of UnaryFunction  
    | Binary of BinaryFunction 
    | Boolean of BooleanFunction 

// ... 

let evaluate f = // signature: Functions -> string 
    match f with 
    | Unary u -> 
     let test_result = u 3 
     sprintf "the result of the unary function is %d" test_result 
    | Binary b -> 
     let test_result = b 315 42 
     sprintf "the result of the binary function is %d" test_result 
    | Boolean o -> 
     let test_result = o 315 42 
     if test_result then "yeah" else "nope" 

Một khi bạn đã làm điều này, bạn có thể gọi cho họ khi cần thiết (như dưới đây, cho thấy FSI đầu ra):

> evaluate (Unary (fun x -> x + 3));; 
val it : string = "the result of the unary function is 6" 

> let someBinaryFunction x y = x * y;; 
val someBinaryFunction : x:int -> y:int -> int 

> Binary someBinaryFunction |> evaluate;; 
val it : string = "the result of the binary function is 13230" 
+1

** Tôi yêu bạn, Sir! ** Bằng cách nào đó, điều này đã không làm việc trước cho tôi (Tôi phát hiện ra rằng đó là do một lỗi đánh máy). Do đó tôi nghĩ rằng điều đó là không thể ... – Unknown6656