2016-08-30 3 views
5

У меня есть, может быть, необычный вопрос, но , как соответствует ли функция F # с использованием соответствия шаблону?Образец соответствует функции в F #

Представьте себе следующее:
У меня есть несколько подписей функций, которые будут использоваться несколько раз, как:

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

Теперь представьте себе функцию evaluate, которая сама принимает функцию f. Подпись fдолжна быть быть одной из перечисленных выше. Как я могу сопоставить такой случай?


Я попытался следующие вещи:
Тест № 1: Использование делегатов и союзов:

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" 

Тест №2: Использование сопоставления с образцом типа и делегатов:

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" 


Проблема с этими примерами заключается в том, что делегаты из ... будут сопоставлены вместо фактических функций. Я хотел бы видеть, как это somethink:

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 # имеет специальный синтаксис для сопоставления функции шаблона?
А если нет, то почему? Я что-то упускаю, или не важно также иметь возможность сопоставлять функции так же, как и все остальное, поскольку это функциональный язык?

+4

Зачем вам нужно использовать делегаты вместо функций? –

+0

@FyodorSoikin: Я пробовал это раньше, но из-за опечатки (чего я тогда не понимал) я не мог определить типы как функции. Поэтому я думал, что это невозможно:/ – Unknown6656

ответ

10

Вместо использования делегатов, просто определить работу, используя функции непосредственно:

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" 

После того, как вы сделали это, вы можете называть их по мере необходимости (как показано ниже, показывая выход FSI):

> 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

** Я действительно люблю тебя, сэр! ** Как-то это не сработало раньше для меня (я обнаружил, что это было из-за опечатки). Поэтому я думал, что это невозможно ... – Unknown6656

Смежные вопросы