2013-01-29 2 views
-1

Я задал этот вопрос несколько дней назад, но теперь у меня больше понимания по этому вопросу. Но у меня все еще возникает проблема, что оператор и операнд не согласны:SML currying (функциональный прог)?

Использование ListPair.foldr Мне нужно создать функцию zipWith, которая объединяет по два списка. Тип функции в целом должно быть:

zipWith : ('a * 'b -> 'c) -> 'a list -> 'b list -> 'c list 

ListPair.foldr : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c 

- zipWith (fn (x, y) => x + y) [1,2,3,4] [10,20,30,40]; 
    val it = [11,22,33,44] : int list 

Моя попытка:

fun zipWith xs ys = ListPair.foldr(zipWith(x,y,z) => (x+y)::z) 0 xs ys 
+0

См. Мой ответ на аналогичный вопрос http://stackoverflow.com/q/14551062/634025 – pad

+0

Хорошо, я был близок haha ​​ – user2012107

ответ

4

Есть несколько вещей неправильно в вашей попытке:

  1. Параметры. У вас есть zipWith xs ys, но тип говорит, что первый параметр должен быть функцией, поэтому измените его на zipWith f xs ys.
  2. Вы вызываете zipWith рекурсивно. Однако ListPair.foldr позаботится об этом для вас, поэтому нет.
  3. Вы передаете 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, и все готово.

+0

Большое спасибо за объяснение.Я понял. – user2012107

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