繁体   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