Обратное каррирование?

Я бы хотел составлять функции определенным образом. Пожалуйста, рассмотрите эти 2 функции в псевдокоде (не F #).

F1 = x + y
F2 = F1 * 10 // note I did not specify arguments for F1, 'reverse curry' for lack of a better word

Я бы хотел, чтобы F # понял, что, поскольку

let F1 x y = x + y
//val F1 : int -> int -> int

код let F2 = F1 * 10 даст мне ту же подпись как F1: val F2: int -> int -> int , а вызов F2 2 3 приведет к 50: (2 + 3) * 10. Это было бы довольно умно. ..

Происходит совсем другое. Первая строка идет как ожидалось:

let F1 x y = x + y
//val F1 : int -> int -> int

, но когда я добавляю вторую строку , пусть F2 = F1 * 10 , она сбрасывает F #. Он жалуется, что тип int не соответствует типу 'a ->' b -> 'c и что F1 теперь требует члена (+) .

Я, конечно, мог бы изложить это так:

let F1(x, y) = x + y
let F2(x, y) = F1(x, y) * 10

Но теперь я мог бы использовать C #, мы уже не так далеко. Кортежные аргументы сильно нарушают элегантность F #. Кроме того, мои настоящие функции F1 и F2 имеют гораздо больше аргументов, чем просто 2, так что это заставляет меня коситься, именно от того, что я хотел избежать, используя F #. Сказать так было бы гораздо естественнее:

let F1 x y = x + y
let F2 = F1 * 10

Могу ли я (почти) сделать это?

Для дополнительных благодарностей: что именно происходит с этими сообщениями об ошибках? Почему вторая строка позволяет F2 = F1 * 10 изменять набор текста в первой?

Заранее благодарим за ваши мысли,

Gert-Jan

update Кроме того, мои настоящие функции F1 и F2 имеют гораздо больше аргументов, чем просто 2, так что это заставляет меня коситься, именно от того, что я хотел избежать, используя F #. Сказать так было бы гораздо естественнее:

let F1 x y = x + y
let F2 = F1 * 10

Могу ли я (почти) сделать это?

Для дополнительных благодарностей: что именно происходит с этими сообщениями об ошибках? Почему вторая строка позволяет F2 = F1 * 10 изменять набор текста в первой?

Заранее благодарим за ваши мысли,

Gert-Jan

update Кроме того, мои настоящие функции F1 и F2 имеют гораздо больше аргументов, чем просто 2, так что это заставляет меня коситься, именно от того, что я хотел избежать, используя F #. Сказать так было бы гораздо естественнее:

let F1 x y = x + y
let F2 = F1 * 10

Могу ли я (почти) сделать это?

Для дополнительной благодарности: что именно происходит с этими сообщениями об ошибках? Почему вторая строка позволяет F2 = F1 * 10 изменять набор текста в первой?

Заранее благодарим за ваши мысли,

Gert-Jan

update что именно происходит с этими сообщениями об ошибках? Почему вторая строка позволяет F2 = F1 * 10 изменять набор текста в первой?

Заранее благодарим за ваши мысли,

Gert-Jan

update что именно происходит с этими сообщениями об ошибках? Почему вторая строка позволяет F2 = F1 * 10 изменять набор текста в первой?

Заранее благодарим за ваши мысли,

Gert-Jan

update Два приложения, которые (почти) делают то, что описано.

Один использует кортеж. Вторая строка выглядит немного необычно, первая работает нормально. Небольшой недостаток в том, что сейчас я не могу использовать каррирование или мне придется добавить еще более необычный код.

let F1 (a, b) = a + b
let F2 = F1 >> (*) 10

F2(2, 3) // returns 50

Другой подход - использование записи. Это немного проще и легче понять на первый взгляд, но требует больше кода и церемоний. Удаляет некоторую элегантность F #, больше похоже на C #.

type Arg (a, b) =
    member this.A = a
    member this.B = b

let F1 (a:Arg) = a.A + a.B
let F2 (a:Arg) = F1(a) * 10

F2 (Arg(2, 3)) // returns 50
7
задан gjvdkamp 5 May 2011 в 08:40
поделиться