Я хотел бы составить функции определенным образом. Пожалуйста, рассмотрите эти 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
но когда я добавляю вторую строку let F2 = F1 * 10
, она сбрасывает F#. Он жалуется, что the type int does not match the type 'a -> 'b -> 'c
и что F1 теперь requires member ( + )
.
Я мог бы, конечно, написать так:
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
Можно ли (почти) это сделать?
Для дополнительных кредитов: что именно происходит с этими сообщениями об ошибках? Почему вторая строка let F2 = F1 * 10
меняет набор текста на первую?
Заранее спасибо за ваши мысли,
Герт-Ян
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
F1
принимает кортеж, тоF2
можно записать какlet F2 = F1 >> (*) 10
- person ildjarn   schedule 04.05.2011