2014-12-27 10 views
6

Mam problemy ze zrozumieniem działania tej funkcji. Funkcja ma przyjmować ciąg znaków i rozdzielać ten ciąg na parę, której pierwszy element jest pierwszym "słowem" w łańcuchu, a drugi element jest pozostałością łańcucha wejściowego.Problemy ze zrozumieniem działania rekursji krotki w Haskell

W szczególności, w linii 6, rozumiem, dlaczego funkcja powinna kończyć się, gdy isSpace c jest prawdziwa, ale nie rozumiem, dlaczego powinna ona zwrócić krotkę z pierwszym elementem będącym pustą listą. Zastanawiałem się, czy ktoś mógłby wyjaśnić, dlaczego działa to przy stosunkowo prostym (ale nietrywialnym) przykładzie, takim jak nextWord "an apple".

import Data.Char 
nextWord :: String -> (String, String) 
nextWord [] 
    = ([],[]) 
nextWord (c:cs) 
    | isSpace c = ([], cs) 
    | otherwise = (c: word, other) 
    where 
    (word, other) = nextWord cs 

EDIT: Jako przykład tego, co ta funkcja zwraca kiedy dany spór zaczyna się od miejsca, nextWord „cześć” powinien powrócić („”, „hello”).

+1

„dlatego, że należy powrócić krotki z pierwszą element będący pustą listą ". Co powinien jednak zwrócić? –

+0

Czy możesz zapisać tę wartość w Haskell? –

+0

To nie jest rekursja krotki. Jest to funkcja rekurencyjna zwracająca krotkę. W przypadku typu "spac" zwraca pustą listę jako pierwszy składnik: jest to właściwie pusty ciąg.Dzieje się tak, aby wywołanie rekurencyjne mogło dodać znaki przed tym, aby wyizolować pierwsze słowo w łańcuchu wejściowym. – chi

Odpowiedz

7

Przejdźmy przez to!

nextWord "an apple" 

Od "an apple" nie wzór mecz przeciwko [], jesteśmy w drugim przypadku. Podstawiając 'a': "n apple" dla c : cs, otrzymujemy:

nextWord ('a':"n apple") 
    | isSpace 'a' = ([], "n apple") 
    | otherwise = ('a': word, other) 
    where 
    (word, other) = nextWord "n apple" 

isSpace 'a' jest False, więc ten upraszcza się

nextWord ('a':"n apple") = ('a': word, other) 
    where (word, other) = nextWord "n apple" 

Podobnie dla nextWord "n apple" otrzymujemy

nextWord ('n':" apple") = ('n': word, other) 
    where (word, other) = nextWord " apple" 

I nextWord " apple" otrzymujemy

nextWord (' ':"apple") 
    | isSpace ' ' = ([], "apple") 
    | otherwise = ('a': word, other) 
    where 
    (word, other) = nextWord "n apple" 

co upraszcza do

nextWord (' ':"apple") = ([], "apple") 

zastępująca powrotem do naszej wypowiedzi dla nextWord "n apple" otrzymujemy

nextWord ('n':" apple") = ('n': word, other) 
    where (word, other) = ([], "apple") 

który upraszcza do

nextWord ('n':" apple") = ('n':[], "apple") 

lub

nextWord ('n':" apple") = ("n", "apple") 

Teraz podstawiając że z powrotem do naszego wyrazu dla nextWord "an apple" otrzymujemy

nextWord ('a':"n apple") = ('a': word, other) 
    where (word, other) = ("n", "apple") 

który upraszcza do

nextWord ('a':"n apple") = ('a':"n", "apple") 

lub

nextWord ('a':"n apple") = ("an", "apple") 
Powiązane problemy