2013-04-27 17 views
5

私は1ヶ月ほど自分自身にハスケルを教えてきましたが、今日は16番目の問題の解決策を読んでいて、質問がありました。ここでリストからn番目の要素を削除

がリンクである:http://www.haskell.org/haskellwiki/99_questions/Solutions/16

基本的に、この質問は、リストからすべてのN番目の要素をドロップ機能を作成するように求められます。例えば 、

*Main> dropEvery "abcdefghik" 3

"abdeghk"

リンクの最初のソリューションは、dropEveryがdropEveryは「の世話をすることができますしながら、空のリストの場合を定義し、なぜ私の質問がある

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 

です空リスト? 私はdropEvery [] _ = []を単に排除して、次のように他の文章を少し変更するだけで、上記と全く同じように動作し、より短く見えるはずだと思います。

誰でも私がこれについて把握するのを助けることができますか?

+1

この関数の引数の順序は「間違っています。このような関数は、通常はInt - > [a] - > [a] 'であり、通常はパイプラインの状況でははるかに便利です。なぜ彼らはその例の中でそれを反対に置いても、私は分かりません。 – leftaroundabout

答えて

7

私は彼らは同じだと思うし、作者はあなたが示唆したようにコードを単純化できたと思う。それの地獄のために私はQuickCheckと両方のバージョンを試して、彼らは同じように見えます。


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 

そして、GHCiの中で、あなたは

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

を行うことができます彼らは同じように見えるので、私はまた、手で

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

をいくつかのコーナーケースをテストしました。

だから、私たちの学習成果:

  1. Quickcheckは自分を過小評価しないでくださいもの
  2. この種のに最適です。 :)
+0

ありがとうございました!私の推測が正しいことを聞いてうれしい。私はクイックチェックについて知らなかった。 GHCを使用する必要がありますか? – Tengu

+0

@TenguあなたはGHCを使用していませんか? 'runghc'や' ghci'も使えますが、QuickCheckはまったく別のコンパイラでも動作します。あなたはインストールガイドのためにgoogleすることができますが、非常に一般的なライブラリなので、インストールするのはとても簡単です。 – Tarrasch

+0

先月、Haskellを始めました。私はGHCコンパイラを使ったことが一度もありません。 (まあ実際には、コンパイラというのは、コンピュータサイエンス専攻の私の友人が何度も私のために説明したにもかかわらず、最初は何を意味するのかわからない)私はQuickCheckを調べるだろうが、あなたの答えをありがとう! – Tengu

関連する問題