【问题标题】:How does this let clause work?这个 let 子句是如何工作的?
【发布时间】:2018-12-16 00:42:30
【问题描述】:

我是 Haskell 的初学者,我不明白这段代码 sn-p 是如何工作的。我不明白 'let' 声明中发生了什么,在调用 'split xys' 之后 (ls1,ls2) 会得到什么?

split :: [(a, b)] -> ([a], [b])
split [] = ([], [])
split ((x, y):xys) = let (ls1, ls2) = split xys
                     in
                     (x:ls1, y:ls2)

让我们用一个简短的例子来解释第一次递归迭代:

如果这是调用:split [(1,2),(3,4)]split xys 在第一次迭代中返回什么?由于“让”,(ls1,ls2)会发生什么?

【问题讨论】:

  • Split 返回一个元组,let 通过模式匹配将变量绑定到元组的元素。
  • 是不是递归让你困惑?

标签: haskell functional-programming


【解决方案1】:
split :: [(a, b)] -> ([a], [b])

split 是一个接收一对列表并返回一对列表的函数。它是使用递归定义的:

split [] = ([], [])

拆分空列表会产生两个空列表。

split ((x, y):xys) =

这个等式定义了如何通过模式匹配来拆分包含至少一个元素的列表。列表中第一对的两部分将被称为xy,而列表的其余部分——无论第一对之后剩下的部分——将被称为xys

                    let (ls1, ls2) = split xys

该子句将根据递归调用来定义。我们获取其中没有第一对的列表,并在其上调用split,记住,这将返回一对两个列表。我们再次使用模式匹配,所以ls1ls2 将是这两个列表。

                    in (x:ls1, y:ls2)

我们必须返回一对新的列表。第一个列表将包含递归调用的第一个列表,加上我们在递归之前切断的对的第一部分。第二个列表同样包含来自递归调用的第二个列表,加上我们在递归之前切断的对的第二部分。

示例:

split [(1,2),(3,4)]:这不是拆分空列表,所以第二个等式匹配。 x 绑定到1y 绑定到2xys 绑定到[(3, 4)]。我们在[(3, 4)] 上递归调用 split。在这个递归执行中,x3y4xys[]。我们再次递归调用split,这次匹配基本情况并返回([], [])。在第一次递归调用中,这意味着ls1 绑定到[]ls2 绑定到[]。所以x:ls1[3]y:ls2[4],所以这个递归调用返回([3],[4])。原始调用得到这个结果,所以ls1 绑定到这对的第一个组件[3],而ls2 绑定到第二个组件[4]。因此x:ls1[1, 3]y:ls2[2, 4]。因此顶级调用返回([1, 3], [2, 4])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2012-07-12
    • 2016-07-15
    • 1970-01-01
    相关资源
    最近更新 更多