我一直在教自己Haskell一个月左右,今天我正在阅读第16个问题的解答,并提出了一个问题。
这是一个链接:http://www.haskell.org/haskellwiki/99_questions/Solutions/16
基本上,这个问题要求创建一个从列表中删除第N个元素的函数。
例如,*Main> dropEvery "abcdefghik" 3
"abdeghk"
链接中的第一个解决方案是
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定义空列表的情况,而dropEvery'可以处理空列表?
我认为可以简单地消除
dropEvery [] _ = []
并修改一些其他句子,因为以下内容应与上述内容完全相同,并且看起来更短。dropEvery :: [a] -> Int -> [a]
dropEvery 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
谁能帮我解决这个问题?
最佳答案
我认为它们是相同的,作者可以按照您的建议简化代码。对于这个问题,我尝试了两种版本的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
[]
因此,它们似乎是相同的。
因此,我们的学习成果: