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?
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?
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.
Myślę, że OP był bardziej zainteresowany tym, dlaczego "nie" powoduje błąd dla wejść ujemnych. – ErikR
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
@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
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
Mnmn, +1, w przypadku, gdy podasz, zawijanie '' (max 0 WYRA) 'nie wydaje się być tak wielkim wysiłkiem. – false
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