Есть несколько вещей неправильно в вашей попытке:
- Параметры. У вас есть
zipWith xs ys
, но тип говорит, что первый параметр должен быть функцией, поэтому измените его на zipWith f xs ys
.
- Вы вызываете zipWith рекурсивно. Однако ListPair.foldr позаботится об этом для вас, поэтому нет.
- Вы передаете ListPair.foldr 0 в качестве стартового значения. Fold-функции всегда принимают начальное значение того же типа, что и возвращаемое значение - мы хотим, чтобы zipWith возвращал список, поэтому функция fold-function должна принимать список в качестве стартового значения. Пустой список.
Подумайте, как работает ListPair.foldr. Мы можем сделать это по одному параметру за раз. Тип ListPair.foldr является:
fn : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c
первый параметр является функцией с типом:
fn : 'a * 'b * 'c -> 'c
Давайте создадим функцию игрушку в качестве примера:
fun foo (a, b, acc) = a+b :: acc
Эта функция принимает два числа и список, добавляет два числа вместе, помещает их перед списком и возвращает его. Тип:
fn : int * int * int list -> int list
Что соответствует нашей сигнатуре типа из первого параметра ListPair.foldr.
Теперь давайте посмотрим на тип ListPair.foldr foo
.
fn : int list -> int list * int list -> int list
Следующий параметр - это список int - начальное значение для складывания. Отлично, мы уже поняли, что это пустой список. Тип ListPair.foldr foo []
является:
fn : int list * int list -> int list
Последний параметр представляет собой кортеж, содержащий два списка. Ставим в некоторых случайных списков, и попробовать его в SML переводчика:
- ListPair.foldr foo [] ([1,2,3],[10,20,30])
> val it = [11, 22, 33] : int list
Теперь все, что вам нужно сделать, это заменить параметры на ListPair.foldr (Foo и два случайных списков) с параметрами из zipWith, и все готово.
См. Мой ответ на аналогичный вопрос http://stackoverflow.com/q/14551062/634025 – pad
Хорошо, я был близок haha – user2012107