2014-11-27 18 views
10

take (-1) [] jest [].Dlaczego funkcja jest całkowita

Jakie są powody, aby preferować tę funkcję częściowo, to znaczy błąd?

Czy istnieją przypadki użycia tej nieruchomości?

+3

Uwaga: to nie jest przypisany do Haskell. Na przykład w Pythonie indeksowanie poza granicami podnosi 'IndexError', ale krojenie * nigdy * podnosi" IndexError ": gdy plasterek jest poza granicami, po prostu zwraca pustą listę. Pisałem kodowanie w Pythonie i muszę powiedzieć, że to zachowanie jest * to, czego pragniesz * z pragmatycznego punktu widzenia. Pozwala to na niechlujstwo podczas krojenia, dzięki czemu kod jest mniejszy i łatwiejszy, a 99,9% czasu i tak pusta lista byłaby poprawnym wynikiem ... – Bakuriu

Odpowiedz

4

Dzielenie listę w kawałki (co najwyżej) n kawałki wymaga take być razem:

chunks n [] = [] 
chunks n xs = take n xs : chunks n (drop n xs) 

Również obecna definicja zapewnia

take n xs ++ drop n xs == xs 

dla każdego n i xs.

Prawdopodobnie powinniśmy mieć zarówno takeAtMost, jak i takeAtLeast, przy czym ten ostatni jest wariantem częściowym (lub zamiast tego powraca Maybe).

Podobna obawa wynika z zip, która również jest całkowita, nawet jeśli dotyczy list o różnej długości. Nadal jest często wykorzystywany w idiomie zip [1..] xs, który paruje każdy element listy z własnym indeksem.

Należy jednak pamiętać, że nie twierdzę, że całkowita funkcja jest zawsze preferowana. W wielu zadaniach programistycznych uzyskanie wyjątku pokazującego błąd jest błogosławieństwem w porównaniu z uzyskaniem wyniku i nie mając pojęcia o tym, gdzie znajduje się błąd. Albo jeszcze gorzej, otrzymując błędny wynik wiarygodny, a nawet nie odkrywając, że istnieje błąd.

+1

Myślę, że OP był bardziej zainteresowany tym, dlaczego "nie" powoduje błąd dla wejść ujemnych. – ErikR

+0

Prawdopodobnie pomijam twój punkt w twoich przykładach: Wydaje się, że zawsze powracają do "upuszczania", które - wtedy - musiałoby być odpowiednio zdefiniowane – false

+0

@false No tak, ale ważne jest, aby 'wziąć 10 [1,2, 3] == [1,2,3] 'dla' porcji' do działania. Jeśli 'take' byłby częściowy,' kawałki "byłyby częściowe również z wyjątkiem wielokrotności długości' n'. – chi

7

take i drop są podobne do funkcji lewego podciągu i prawego podłańcucha, a w praktyce udowodniono, że są wygodne dla osób, które nie podnoszą błędu w przypadku ujemnych lub nieprawidłowych długości.

Na przykład - funkcja padding:

pad :: Int -> String -> String 
pad n str = (repeat (n - length str) ' ') ++ str 

i tutaj jest wariantem pad z innym ciągiem:

padWith :: String -> Int -> String -> String 
padWith field n str = (take (n - length str) field) ++ str 
+0

Mnmn, +1, w przypadku, gdy podasz, zawijanie '' (max 0 WYRA) 'nie wydaje się być tak wielkim wysiłkiem. – false

Powiązane problemy