【问题标题】:Haskell style: Pattern matching vs. more intuitive solutionsHaskell 风格:模式匹配与更直观的解决方案
【发布时间】:2018-10-07 02:24:32
【问题描述】:

我刚刚开始使用 Haskell,所以我正试图围绕“Haskell 的思维方式”展开思考。是否有理由使用模式匹配来解决问题 1 here 基本上是通过展开整个列表并递归调用函数,而不是像 myLast lst = lst !! ((length lst) - 1) 那样直接检索最后一个元素?这看起来几乎是蛮力的,但我认为这只是我对这里的不熟悉。

【问题讨论】:

  • 我认为“Haskell 的思维方式”实际上会对这个问题产生误解,因为 myLast 显然是片面的——myLast [] 是什么意思?因此,结果类型应扩大到 Maybe a 或参数类型应缩小到 NonEmpty a,但这可能对您的问题没有多大帮助。
  • 在处理列表类型时,headtailinitlast 是你的朋友,但正如前面提到的,在某些其他语言中,列表不如数组有效。 Haskell 中有更好的数据结构。看看stackoverflow.com/questions/9611904/…

标签: haskell


【解决方案1】:

我能想到的几点:

  • (!!)length 最终是通过对列表结构的递归来实现的。既然如此,使用显式递归来实现这些基本功能可能是一个值得学习的练习。

  • 请记住,在后台,最后一个元素的检索不是直接的。由于我们正在处理链表,length 必须遍历列表的所有元素,(!!) 必须遍历所有元素直到所需的索引。既然如此,lst !! (length lst - 1) 会遍历整个列表两次,而不是一次。 (根据经验,这就是为什么最好避免使用 length 的原因之一,除非您实际上需要知道元素本身的数量,而不仅仅是作为其他事物的代理。)

  • 模式匹配是一种简洁的方式来陈述有关数据类型结构的事实。如果在递归地使用列表时,您匹配[x] 模式(或者,等效地,x : [] - 一个与空列表相结合的元素),您知道x 是最后一个元素。在某种程度上,匹配[x] 所涉及的间接级别比访问索引length lst - 1 处的列表元素要少,因为它只处理列表的结构,而不需要将索引方案固定在其顶部。

话虽如此,您认为显式递归感觉“几乎是蛮力”的感觉从根本上说是正确的。随着时间的推移,您会发​​现折叠、映射函数和其他捕获和抽象常见递归模式的方法,从而使以更流畅的方式编写成为可能。

【讨论】:

  • 请注意(!!) 也是一个偏函数。避免(!!) 通常是一种很好的形式——因此您可以明确地处理相关的边缘情况。
猜你喜欢
  • 2023-03-26
  • 2015-08-29
  • 2019-01-13
  • 2011-07-05
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
相关资源
最近更新 更多