[英]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
你快到了
首先分別定義除法函數
div3 :: Int -> Maybe Int -> Maybe Double div3 i (Just n) | n > 0 = Just (fromIntegral i / fromIntegral n) div3 i _ = Nothing
然后,對於列表中的每個項目,調用div3
並將其與對divideList
的遞歸調用的結果連接起來,如下所示
divideList :: Int -> [Maybe Int] -> [Maybe Double] divideList _ [] = [] divideList m (x:xs) = (div3 mx):(divideList m xs)
這里,
divideList _ [] = []
稱為遞歸的基本條件 。 這決定了您的遞歸何時結束。
我總是建議這樣做:不要像您想做的那樣編寫直接的遞歸解決方案。 它們不是慣用語言,它們更難閱讀,一旦完成復雜的工作,它們就會變得很難編寫。
相反,請找出如何使用標准庫函數(例如map
, filter
等)編寫解決方案的方法。 然后,作為練習,編寫您自己的那些庫函數的版本。 在這種情況下:
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.