Używanie ListPair.foldr do implementacji zipWith w SML

Tło: poziom początkujący w SML

Moje zadanie wymaga użycia ListPair.foldr i tylko tej funkcji do zaimplementowania funkcji zipWith.

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

ListPair.foldr zwraca pojedynczy element c, podczas gdy zipWith zwraca listę 'c', więc naturalnie moje podejście wielokrotnie używałoby ListPair.foldr do wyrzucania pojedynczych elementów c, które następnie umieszczałem na mojej liście c. ListPair.foldr pobiera parę list i składa je jedna nad drugą zgodnie z dostarczoną funkcją, więc jedynym sposobem uzyskania pożądanego efektu byłoby pobranie jednego elementu z każdej listy na raz, przesłanie go do ListPair.foldr jako para list, weź wynik i połącz go z następną rundą. Musiałbym także przekonwertować funkcję z ('a *' b -> 'c) na (' a * 'b *' c -> 'c). Tak jak:

fun zipWith f [] l2 = []
| zipWith f l1 l2 = 
let val f2 = fn (a,b,c)=> f(a,b)+c   (* converting the function *)
    val xh = [hd(l1)]      (*first element of 'a list, as a list itself *)
    val yh = [hd(l2)]      (*first element of 'b list, as a list itself *)
    val xt = tl(l1)        (*taking the tail of 'a list*)
    val yt = tl(l2)        (*taking the tail of 'b list*)
in
    ListPair.foldr f2 0 (xh, yh)::    (*perform the operation with the two heads*)
    zipWith f xt yt                   (*recursively call zipWith with the remainder*)
end;

To działa.

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

Ale teraz trudna część: nie powinienem tego robić rekurencyjnie, to znaczy nie mogę wywołać zipWith w mojej funkcji zipWith. Czy to możliwe? Z tego co przeczytałem, rzeczywista funkcja zipWith w Haskell jest zdefiniowana rekurencyjnie; jak to zrobić bez rekursywnie?

Nie wyobrażam sobie, żeby profesor namawiał nas do zrobienia tego w sposób zorientowany obiektowo za pomocą pętli while i takich (próbowałem mimo to, mój poziom nie jest wystarczający nawet do tego).

Czy jestem w zupełnie złym kierunku? Jak mam podejść do tego pytania?

----------------- Odpowiedzi ----------------

Na początku wypróbowałem rozwiązanie padów:

fun zipWith f l1 l2 = 
let val f2 = fn (a,b,c)=> f(a,b)::c
in
    ListPair.foldr f2 0 l1 l2
end;

Ale to nie zadziałało, ponieważ dodawałem go do 0 zamiast []. Rodzaje się nie sprawdziły i nie mogłam tego zrozumieć!

Dziękuję Ci!

questionAnswers(1)

yourAnswerToTheQuestion