Verwenden von ListPair.foldr zum Implementieren von zipWith in SML

Hintergrund: Anfänger bei SML

Für meine Aufgabe muss ich ListPair.foldr verwenden und nur diese Funktion, um die zipWith-Funktion zu implementieren.

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

ListPair.foldr gibt ein einzelnes c-Element zurück, während zipWith eine c-Liste zurückgibt. Daher würde mein Ansatz ListPair.foldr natürlich wiederholt verwenden, um einzelne c-Elemente auszufüllen, die ich dann in meine c-Liste einfüge. ListPair.foldr nimmt ein Paar von Listen und faltet sie gemäß der bereitgestellten Funktion übereinander. Der einzige Weg, um den gewünschten Effekt zu erzielen, besteht darin, jeweils ein Element aus jeder Liste zu nehmen und es als ein Element an ListPair.foldr zu senden Listenpaar, nimm das Ergebnis und verkette es zur nächsten Runde. Ich müsste auch die Funktion von ('a *' b -> 'c) in (' a * 'b *' c -> 'c) konvertieren. Wie so:

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;

Das funktioniert.

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

Aber jetzt der knifflige Teil: Ich soll das nicht rekursiv machen, das heißt, ich kann zipWith nicht innerhalb meiner zipWith-Funktion aufrufen. Ist das überhaupt möglich? Nach dem, was ich gelesen habe, ist die eigentliche zipWith-Funktion in Haskell rekursiv definiert. Wie mache ich das nicht rekursiv?

Ich kann mir nicht vorstellen, dass der Professor uns auffordert, dies objektorientiert mit while-Schleifen und dergleichen zu tun (ich habe es trotzdem versucht, mein Niveau ist auch dafür nicht ausreichend).

Bin ich in die völlig falsche Richtung? Wie soll ich mich dieser Frage nähern?

-----------------Antwortete----------------

Eigentlich habe ich zuerst Pad's Lösung ausprobiert:

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

Aber es hat nicht funktioniert, weil ich es an 0 anstatt an [] angehängt habe. Die Typen haben nicht funktioniert und ich konnte es nicht herausfinden!

Vielen Dank!

Antworten auf die Frage(1)

Ihre Antwort auf die Frage