【问题标题】:Understanding recursion in a function that converts list of Maybe a to Maybe [a]了解将 Maybe a 列表转换为 Maybe [a] 的函数中的递归
【发布时间】:2021-11-10 09:36:48
【问题描述】:

在学习 Haskell 时,我遇到了这个 flipMaybe 函数:

flipMaybe :: [Maybe a] -> Maybe [a]
flipMaybe [] = Just []
flipMaybe (Nothing:xs) = Nothing
flipMaybe (Just x:xs) = case flipMaybe xs of  
    Nothing -> Nothing
    Just ls  -> Just (x:ls)

我无法理解最后一行。 ls 这里是什么?递归在这里如何工作?或者换句话说,有人可以告诉我这个函数是如何解决flipMaybe [Just 1, Just 2, Just 3] 的吗? (一步一步)

【问题讨论】:

  • ls 是包裹在递归的Just 中的数据,所以如果flipMaybe [Just 2, Just 3]Just(这里是Just [2, 3],那么ls 是一个列表[2, 3]因此,它以x 开头,并包裹在Just 中。
  • flipMaybe [Just 1, Just 2, Just 3] --> case flipMaybe [Just 2, Just 3] of ... --> case Just [2, 3] of Nothing -> Nothing; Just ls -> Just (1: ls) --> Just (1:[2, 3])
  • 也就是说case ... of ...中的Just ls是模式匹配,类似于filpMaybe定义中的Just x:xs模式匹配。但是这一次,我们不是对函数的输入进行模式匹配,而是对递归调用flipMaybe xs 的输出进行模式匹配
  • 您在这里实现的是sequencem ~ Maybet ~ [] 的特例。

标签: haskell recursion


【解决方案1】:

我无法理解最后一行。这里的ls 是什么?

如果列表尾部的递归调用返回Just ls,则ls 是包裹在Just 中的列表。所以如果flipMaybe [Just 3]被调用,这将返回一个Just [3],因此ls[3]

这用于在列表前面加上xs。如果我们因此评估flipMaybe [Just 1, Just 2],那么我们首先检查第一项,如果那是Nothing,我们返回Nothing:我们不关心列表的其余部分,我们知道结果将是@ 987654333@,如果是Just …,我们应该检查flipMaybe [Just 2]会返回什么。如果它返回一个Nothing,那么我们就返回Nothing,因为这意味着在列表的尾部有一个Nothing。如果它是Just ls,那么我们返回一个Just (x : ls),因此我们将列表项添加到递归调用的结果中。

如果列表因此看起来像[Just 2, Nothing, Just 3],那么我们首先调查Just 2,因为它不是Nothing,我们使用flipMaybe [Nothing, Just 3] 进行递归调用。由于该列表以Nothing 开头,因此NothingflipMaybe [Nothing, Just 3] 返回,因此我们为flipMaybe [Just 2, Nothing, Just 3] 返回Nothing

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多