Sto imparando la ricorsione della coda e sto riscontrando alcune difficoltà nel determinare se la mia funzione è ricorsiva della coda o meno (principalmente su funzioni che uso un'altra funzione).Queste funzioni sono ricorsive?
Ho implementato le due seguenti funzioni, ma non sono sicuro che siano ricorsive o meno.
Il primo è una funzione per concatenare due elenchi.
conca list [] = list
conca [] result = result
conca (h:t) result = conca (init (h:t)) (last(h:t):result)
concatenate::[a]->[a]->[a]
concatenate list1 list2 = conca list1 list2
I calcoli nella funzione vengono elaborati prima della chiamata ricorsiva, ma il suo utilizzo e ultimo init, che non sono coda ricorsiva (ho controllato loro definizione in http://ww2.cs.mu.oz.au/172/Haskell/tourofprelude.html)
La seconda funzione è quella di rimuovere la prima occorrenza di un dato numero in una data lista.
invert [] result = result
invert (h:t) result = invert t (h:result)
remov n [] aux result = invert result []
remov n (h:t) aux result
| aux==1 = remov n t 1 (h:result)
| n==h = remov n t 1 (result)
| otherwise = remov n t 0 (h:result)
remove n list = remov n list 0 []
L'aux parametro (che possono assumere 0 o 1 come valore) viene utilizzato per marcare se l'occorrenza è stato rimosso o meno.
Nella funzione di rimozione mentre il risultato parziale è passato attraverso la chiamata ricorsiva la lista viene invertita, al termine la lista è senza la prima occorrenza ma capovolta, quindi deve essere invertita per essere restituita come un risultato.
Probabilmente stai imparando sulla ricorsione della coda per motivi di efficienza. Hai già letto [questa domanda] (http://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)? Spiega perché l'ottimizzazione delle chiamate tail non è esattamente ciò di cui hai bisogno. Inoltre, sul tema dell'efficienza, usare 'init' e' last' molto è un disastro! – AndrewC
Basta leggerlo. In questo caso non sto cercando l'efficienza, ma semplicemente implementando alcune funzioni di base usando la ricorsione della coda, come pratica. Quindi, invece di usare init e last dovrebbe essere un'opzione migliore? – user1493813
'init' e' last' attraversano l'intera lista, quindi sono operazioni _O (n) _. 'head' e' tail' sono _O (1) _, molto meglio da usare, ma è possibile ottenerli per pattern matching. La definizione standard di '(++)' dice '(x: xs) ++ ys = x: (xs ++ ys)', una classica funzione pigro ricorsiva non-tail che produce immediatamente la testa del risultato. – AndrewC