簡體   English   中英

如何編寫以下具有高階函數的 haskell 代碼?

[英]How can I write the following haskell code with higher order functions?

下面的代碼表示一個函數,它將一個列表作為輸入,然后將相同值的后續重復組合到一個子列表中。 例如:pack ['a','a','b','b','b','a'] = [['a','a'], ['b','b', 'b'], ['a']]

 pack :: [Char] -> [[Char]]
 pack (x:xs) = ys : pack zs
     where
        (ys, zs) = takeall x (x:xs)
         takeall _ [] = ([], [])
         takeall x (y:ys)
         | x == y = let (us, vs) = takeall x ys
                                  in (y:us, vs)
         
         | otherwise = ([], (y:ys)) 

我在示例解決方案中找到了此代碼。 我仍然是haskell的初學者,但我曾經看到過類似的問題作為C語言算法的示例。在解決這個問題時,我想到在高階函數的幫助下編寫代碼。我想foldl、filter 和 concatMap 的組合可能是解決這個問題的好方法,但是我不太確定 filter。我想為 filter 編寫一個函數,它遍歷列表並將每個元素與其相鄰元素進行比較,如果他們是 eqaul 返回 true。 編寫這樣的函數可能很容易,但我應該如何將它與其他更高階的函數結合起來,以便將真實的東西放在一起? 你如何用高階函數解決這個問題?

首先,您的takeall函數可以替換為 Prelude 中的span函數:

pack :: [Char] -> [[Char]]
pack (x : xs) = ys : pack zs
  where
    (ys, zs) = span (== x) (x : xs)
pack [] = []

然后,您可以使用unfoldr擺脫顯式遞歸:

import Data.List (unfoldr)

pack2 :: [Char] -> [[Char]]
pack2 = unfoldr go
  where
    go (x : xs) = Just $ span (== x) (x : xs)
    go [] = Nothing
main :: IO ()
main = do
  print $ pack ['a', 'a', 'b', 'b', 'b', 'a']
  print $ pack2 ['a', 'a', 'b', 'b', 'b', 'a']

輸出:

["aa","bbb","a"]
["aa","bbb","a"]

暫無
暫無

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

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