2013-04-27 11 views
5

Uczę się Haskella przez miesiąc lub jakiś czas temu i dzisiaj czytałem rozwiązanie 16. problemu i zadałem pytanie.Upuść n-ty element z listy

Oto link: http://www.haskell.org/haskellwiki/99_questions/Solutions/16

Zasadniczo, to pytanie zadaje zrobić funkcję, która spada każdy element N'th z listy. Na przykład

*Main> dropEvery "abcdefghik" 3

"abdeghk"

Pierwsze rozwiązanie w linku jest

dropEvery :: [a] -> Int -> [a] 
dropEvery [] _ = [] 
dropEvery (x:xs) n = dropEvery' (x:xs) n 1 
    where 
     dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1)) 
     dropEvery' [] _ _ = [] 
     divides x y = y `mod` x == 0 

Moje pytanie brzmi dlaczego dropEvery definiuje przypadku pustych list podczas dropEvery”może zająć pusta lista? Myślę, że dropEvery [] _ = [] można po prostu wyeliminować i zmodyfikować trochę innych zdań, ponieważ poniższe polecenia powinny działać dokładnie tak samo jak powyżej i wyglądają na krótsze.

Czy ktoś może mi pomóc dowiedzieć się o tym?

+1

Należy zauważyć, że kolejność argumentów tej funkcji jest "zła"; takie funkcje są zwykle "Int -> [a] -> [a]", co jest zwykle znacznie bardziej przydatne w sytuacjach związanych z rurociągiem. Dlaczego w tym przykładzie mówią inaczej, nie mam pojęcia. – leftaroundabout

Odpowiedz

7

Sądzę, że są takie same i autor mógł uprościć kod zgodnie z sugestiami. Dla do cholery próbowałem obu wersji z QuickCheck i wydają się być takie same.


import Test.QuickCheck 

dropEvery :: [a] -> Int -> [a] 
dropEvery [] _ = [] 
dropEvery (x:xs) n = dropEvery' (x:xs) n 1 
    where 
     dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1)) 
     dropEvery' [] _ _ = [] 
     divides x y = y `mod` x == 0 

dropEvery2 :: [a] -> Int -> [a] 
dropEvery2 xs n = dropEvery' xs n 1 
    where 
     dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1)) 
     dropEvery' [] _ _ = [] 
     divides x y = y `mod` x == 0 

theyAreSame xs n = (dropEvery xs n) == (dropEvery2 xs n) 
propTheyAreSame xs n = n > 0 ==> theyAreSame xs n 

I ghci można zrobić

*Main> quickCheck propTheyAreSame 
+++ OK, passed 100 tests. 

ja również testowane kilka przypadków narożne ręcznie

*Main> dropEvery [] 0 
[] 
*Main> dropEvery2 [] 0 
[] 
*Main> dropEvery [] undefined 
[] 
*Main> dropEvery2 [] undefined 
[] 

Więc im wydają się takie same.

Więc nasi Efekty kształcenia:

  1. QuickCheck jest idealne do tego rodzaju rzeczy
  2. Nie lekceważ siebie. :)
+0

Dziękuję za odpowiedź! Cieszę się, że moje przypuszczenia były poprawne. Nie wiedziałem o Quickcheck. Czy muszę używać GHC, aby z niego korzystać? – Tengu

+0

@Tengu Nie używasz GHC? Możesz też użyć 'runghc' lub' ghci', ale jestem pewien, że QuickCheck będzie działać również na zupełnie innych kompilatorach. Możesz google znaleźć przewodnik instalacji, ale ponieważ jest to bardzo popularna biblioteka, powinna być bardzo łatwa do zainstalowania. – Tarrasch

+0

Właśnie zacząłem Haskell w zeszłym miesiącu i nigdy nie korzystałem z kompilatora GHC. (Właściwie nawet nie wiem, co oznacza "kompilator", mimo że mój znajomy z informatyki wyjaśnił mi wiele razy haha) Sprawdzę QuickCheck, ale nie jestem przygotowany na takie rzeczy. Dziękuję za Twoją odpowiedź! – Tengu

Powiązane problemy