Как написать функцию, которая получает сумму 2 функции? - PullRequest
0 голосов
/ 04 октября 2018

Мне нужно написать код, который создает функцию, скажем, «f», которая вычисляет сумму двух функций, скажем, «h» и «g».Я написал это так:

let h x = x + 2;;
let g x = x + 4;;
let f h x g x = h x + g x;;

Но когда я печатаю, скажем, f h 2 g 4;;, это показывает мне 14, что неправильно, потому что это должно показывать мне 12. Почему?

Также можно ли как-нибудь сделать так, чтобы я мог выбирать, какие функции суммировать, когда я запускаю код, или мне нужно каждый раз устанавливать функции?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Если мы говорим о «сумме двух функций» в математическом смысле, то у нас должна быть функция, которая принимает два параметра g и h, которые оба являются функциями, и возвращает результат, который также являетсяфункция (обычно обозначается g+h, и которая такова, что (g+h)(x) = g(x) + h(x)).

Итак, цель состоит в том, чтобы написать функцию sum, например:

let sum g h =
    ...

, котораявозвращает функцию, которая принимает аргумент x и возвращает f(x) + g(x).

Можно сделать это следующим образом:

let sum g h =
    fun x -> (g x) + (h x)

Вы можете проверить тип sum:

val sum : ('a -> int) -> ('a -> int) -> 'a -> int = <fun>

, что означает:

  • принимает первый аргумент типа ('a -> int) (который является функцией, которая принимает один аргумент и возвращает целое число: то, которое мы вызвалиg),

  • он принимает второй аргумент также типа ('a -> int) (тот, который мы назвали h),

  • это около функциитакже типа 'a -> int, что нам и нужно (поскольку g+h действительно является функцией, которая принимает аргумент и возвращает целое число.

В большинстве языков программирования вы будете вынуждены иметь такое определение функции.В OCaml, благодаря curry и некоторой черной магии, вы можете сказать: «Но подождите, вы решили сгруппировать последние 'a -> int и назвать этот тип возврата sum, но не могли бы вывместо этого может быть, что 'a является третьим аргументом sum и что его тип возвращаемого значения просто int "?И это было бы то же самое, что сказать, что мы можем видеть sum "functor" как функцию, принимающую g и h в качестве аргументов и возвращающую новую функцию, которая при вызове x вернет g(x)+h(x), но мы можем эквивалентно увидеть его как функцию, принимающую три аргумента g, h и x и возвращающую g(x)+h(x).Эти два видения эквивалентны в OCaml.Таким образом, мы можем упростить наш код и просто написать:

let sum g h x = (g x) + (h x)

Вы можете проверить, что тип этого типа все еще

val sum : ('a -> int) -> ('a -> int) -> 'a -> int = <fun>

, как и ожидалось.


Оттуда вы можете получать удовольствие от синтаксиса и определять свой собственный оператор суммирования для функций, например ++, например:

let (++) g h x = (g x) + (h x)

, а затем использовать его после определения g и h:

let g = ( ( + ) 5 )
and h = ( ( * ) 2 )
in
(g ++ h) 3

, который вернет (g+h)(3) = g(3) + h(3) = (5+3) + (2*3) = 14.

0 голосов
/ 04 октября 2018

Вы скрываете параметр x в f, поэтому f h 2 g 4 оценивается как h 4 + g 4.Все, что вам нужно сделать, это назвать один из параметров как-то еще, например y:

let f h x g y = h x + g y;;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...