簡體   English   中英

列表理解遞歸[Haskell]

[英]List Comprehension to Recursion [Haskell]

我有以下函數,該函數用Int輸入划分Maybes列表。

divideList :: Int -> [Maybe Int] -> [Maybe Double]

 divideList 100 [Just 5, Just 4, Nothing]   == [Just 20, Just 25.0, Nothing]

提醒一下,Maybe數據類型定義如下:

 data Maybe a = Nothing | Just a

我的代碼看起來(並可以正常工作)如下:

divideList m xs = [ div2 x | x <- xs]
    where
        div2 (Just n) | n > 0   = Just (fromIntegral m / fromIntegral n)
        div2 _                  = Nothing

現在,我嘗試再次編寫相同的函數,但是這次只是使用遞歸而不使用列表推導。 但是我似乎無法正常工作。

這是我的(錯誤的)猜測:

divideList m xs = div2  x 
    where
        div2 (Just x) | x > 0   = Just (fromIntegral m / fromIntegral x)
        div2 _                  = Nothing

你快到了

  1. 首先分別定義除法函數

     div3 :: Int -> Maybe Int -> Maybe Double div3 i (Just n) | n > 0 = Just (fromIntegral i / fromIntegral n) div3 i _ = Nothing 
  2. 然后,對於列表中的每個項目,調用div3並將其與對divideList的遞歸調用的結果連接起來,如下所示

     divideList :: Int -> [Maybe Int] -> [Maybe Double] divideList _ [] = [] divideList m (x:xs) = (div3 mx):(divideList m xs) 

這里,

divideList _ [] = []

稱為遞歸的基本條件 這決定了您的遞歸何時結束。

我總是建議這樣做:不要像您想做的那樣編寫直接的遞歸解決方案。 它們不是慣用語言,它們更難閱讀,一旦完成復雜的工作,它們就會變得很難編寫。

相反,請找出如何使用標准庫函數(例如mapfilter等)編寫解決方案的方法。 然后,作為練習,編寫您自己的那些庫函數的版本。 在這種情況下:

divideList m xs = map div2 xs
    where
        div2 (Just n) | n > 0   = Just (fromIntegral m / fromIntegral n)
        div2 _                  = Nothing

-- Apply the function `f` to each element of the list, returning a list of the results,
-- in the order of the corresponding arguments.
map f []     = _   -- Fill me in
map f (x:xs) = _   -- Fill me in

我建議首先編寫一個函數,將兩個整數相除。 它必須返回Maybe Double ,因為計算並非總是可行的。

div2 m n = if n <= 0 then Nothing else Just (fromIntegral m / fromIntegral n)

然后,您只需要將此函數應用於列表的每個元素即可,這可以通過map來完成。 然而,隨着數量的“隱藏” Maybe ,你可以使用函數(>>=)以“解包”它(當它是不是Nothing ,它可以停留一個Nothing ,因為我們想要的)。

divideList m xs = map (>>= div2 m) xs

或更短:

divideList m = map (>>= div2 m)

暫無
暫無

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

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