Usando ListPair.foldr para implementar o zipWith no SML

Antecedentes: nível iniciante no SML

Minha tarefa exige que eu use ListPair.foldr e somente esta função para implementar a função 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 retorna um único elemento 'c', enquanto zipWith retorna uma 'c list', então naturalmente minha abordagem usaria ListPair.foldr repetidamente para derramar fora os elementos 'c individuais que eu coloco na minha lista' c '. ListPair.foldr pega um par de listas e as dobra umas sobre as outras de acordo com a função fornecida, então a única maneira de obter o efeito desejado seria pegar um elemento de cada lista de cada vez, alimentá-lo com ListPair.foldr como um par de listas, pegue o resultado e concatene-o para a próxima rodada. Eu também teria que converter a função de ('a *' b -> 'c) para (' a * 'b *' c -> 'c). Igual a:

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;

Isso funciona.

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

Mas agora a parte complicada: eu não deveria fazer isso de forma recursiva, isto é, não posso chamar zipWith dentro da minha função zipWith. Isso é possível? Pelo que eu li, a função zipWith em Haskell é definida recursivamente; como faço isso de maneira não recursiva?

Eu não posso imaginar o professor nos exortando a fazer isso de uma maneira orientada a objetos com loops while e tal (eu tentei de qualquer forma, meu nível não é adequado nem para isso).

Eu estou na direção completamente errada? Como devo abordar essa questão?

-----------------Respondidas----------------

Na verdade, eu tentei a solução de pad no início:

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

Mas não funcionou porque eu estava anexando-o a 0 em vez de []. Os tipos não deram certo e eu não consegui entender!

Obrigado!

questionAnswers(1)

yourAnswerToTheQuestion