簡體   English   中英

有沒有辦法在 Haskell 中使用“<=”進行模式匹配?

[英]Is there a way to use "<=" for pattern matching in Haskell?

我有以下代碼,它刪除列表中的每個第 n 個元素。

dropEvery :: [a] -> Int -> [a]
dropEvery xs n = f xs n ++ dropEvery (drop n xs) n
    where
        f ys 0 = []
        f ys 1 = []
        f [] m = []
        f (y:ys) n = y : (f ys (n-1))

我想讓它更短一點,並且想知道是否有辦法在模式匹配中使用“<=”。 我嘗試使用where子句來執行此操作,但它不起作用,為什么?

f ys m = []
     where
         m <= 1 || ys == []

我怎樣才能逃避這種冗余? 有沒有一種在模式匹配中使用“小於或等於”的好方法?

編輯:我用警衛試過這個

 where
     f ys m
        | m <= 1 || null ys = []
        | otherwise         = (head ys) : (f (tail ys) (n-1))

您可以與警衛一起工作:

dropEvery :: [a] -> Int -> [a]
dropEvery xs n = f xs n ++ dropEvery (drop n xs) n
    where
        f ys i | i <= 1 = []
        f [] _ = []
        f (y:ys) n = y : (f ys (n-1))

如果滿足守衛中的條件,則該子句“觸發”,因此在這種情況下將返回一個空列表[]

但是,您將陷入無限循環,因為您編寫了f xs n ++ dropEvery (n xs) ndrop 3 []將返回[] ,因此它將繼續使用空列表調用dropEvery

您可以使用遞歸,我們每次遞減n直到它達到0 ,然后我們進行兩跳,所以:

dropEvery :: Int -> [a] -> [a]
dropEvery n = go (n-1)
    where go _ [] = []
          go i (x:xs)
              | i <= 0 = go (n-1) xs
              | otherwise = x : go (i-1) xs

我們還可以使用splitAt:: [a] -> ([a], [a])模式保護

dropEvery n [] = []
dropEvery n ds
    | (_:ys) <- sb = sa ++ dropEvery n ys
    | otherwise = sa
    where (sa, sb) = splitAt (n-1) ds

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM