Uczę się rekursji ogona i mam pewne trudności w określeniu, czy moja funkcja jest rekurencyjna czy też nie (głównie w funkcjach, w których używam innej funkcji).Czy te funkcje są rekursywne?
Zaimplementowałem dwie następujące funkcje, ale nie jestem pewien, czy są one rekursywne, czy też nie.
Pierwszy to funkcja łączenia dwóch list.
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
Obliczenia w funkcji są przetwarzane przed rekurencyjnego rozmowy, ale jest za pomocą ostatniego i INIT, które nie są ogon rekurencyjne (I zaznaczone ich definicji w http://ww2.cs.mu.oz.au/172/Haskell/tourofprelude.html)
Drugą funkcją jest usunięcie pierwsze wystąpienie danej liczby w podanej liście.
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 []
droga Aux parametr (który może przyjmować 0 lub 1, a wartość) jest używany do oznaczania, czy wcześniejszego występowania została usunięta czy nie.
W funkcji usuwania, gdy wynik częściowy jest przekazywany przez wywołanie rekursywne, lista jest odwracana, na końcu lista jest bez pierwszej wartości, ale odwrócona, dlatego musi być odwrócona do zwrócenia jako wynik.
Prawdopodobnie dowiadujesz się o rekurencji ogona ze względów wydajnościowych. Czy znasz już to pytanie (http://stackoverflow.com/questions/13042353/does-haskell-have-tail-recursive-optimization)? To wyjaśnia, dlaczego optymalizacja połączeń końcowych nie jest dokładnie tym, czego potrzebujesz. Również na temat wydajności, używanie 'init' i' last' wiele to katastrofa! – AndrewC
Po prostu przeczytaj. W tym przypadku nie szukam wydajności, ale po prostu wykonuję pewne podstawowe funkcje, używając rekurencji ogona, jako praktyki. Więc zamiast używać init i ostatniej, która byłaby lepsza opcja? – user1493813
'init' i' last' oba przechodzą przez całą listę, tak samo są wykonywane operacje _O (n) _. 'head' i' tail' to _O (1) _, o wiele lepsze w użyciu, ale możesz je uzyskać dopasowując do wzorca. Standardowa definicja '(++)' mówi '(x: xs) ++ ys = x: (xs ++ ys)', klasyczna efektywna, nieskończona, rekursywna funkcja leniwy, która natychmiast generuje nagłówek wyniku. – AndrewC