【问题标题】:Haskell- how do I walk and compare down the Array/ListHaskell-我如何遍历和比较数组/列表
【发布时间】:2018-10-24 10:27:51
【问题描述】:

我是 Haskell 的新手,但在其他一些语言方面我是老手。 (这个问题取自一个汇编语言练习,但我想在 Haskell 中解决它。这不是作业或测试问题的一部分)

鉴于: 具有列表内值的数组(列表)遵循以下模式:

第一项小于第二项,第二项大于第三项,第三项小于第四项,依此类推,(“波浪”)。

问题:

1 如何在 Haskell 中解决它? (我知道如何用其他可以处理数组索引的语言来解决它,但我不知道如何用函数式语言来解决它。

  1. 答案是否可以概括,以便解决其他模式?

【问题讨论】:

  • 您如何尝试解决它并发布有关尝试解决方案的哪一部分让您感到困惑或造成麻烦的具体问题?获得一个问题的分数解决方案可能不会在很大程度上帮助您学习该语言。
  • 1.我忘了提到问题是要求一个函数来测试数组是否遵循“波浪模式”。 2.这是一个普遍的问题:如何在不使用循环和数组索引的情况下检查列表中某个项目的特定属性?
  • 1.如果您忘记了什么,您可以编辑问题,而不是在 cmets 中添加新信息。 2.您使用递归和模式匹配(或许多标准函数之一,如map,foldr,filter,这是最接近“循环”的东西)。如果您是 Haskell 的初学者,请尽快学习模式匹配。教程通常会在早期介绍它,因为这在 Haskell 中非常重要。
  • 我投票决定将此问题作为题外话结束,因为在 StackOverflow 上提问并不是学习新编程语言的基本知识的好方法。教程或书籍将以更有条理的方式介绍这些内容。

标签: list haskell


【解决方案1】:

这在 Haskell 中很容易表达

wave :: (Ord a) => [a] -> Bool
wave xs = and $ zipWith3 ($) (cycle [(<),(>)]) xs (tail xs)

我们也可以对模式进行简单的参数化

waveLike :: [(a -> a -> Bool)] -> [a] -> Bool
waveLike patterns xs = and $ zipWith3 ($) (cycle patterns) xs (tail xs)

twoUpTwoDown :: (Ord a) => [a] -> Bool
twoUpTwoDown = waveLike [(<),(<),(>),(>)]

coprimeThenNotCoprime :: (Integral a) => [a] -> Bool
coprimeThenNotCoprime = waveLike [coprime, notCoprime]
  where coprime m n = gcd m n == 1
        notCoprime m n = not (coprime m n)

【讨论】:

  • 非常感谢。我不知道您使用的这些功能是否存在。
【解决方案2】:

Probie's 是一个非常优雅的解决方案,但对于初学者来说,基本递归可能更容易理解。

wave :: (Ord a) => [a] -> Bool
wave []            = True
wave [_]           = True
wave [x1,x2]       = x1 < x2
wave (x1:x2:x3:xs) = x1 < x2 && x2 > x3 && wave (x3:xs)

四行代码如下:

包含 0 个元素的列表是波浪形的。

包含 1 个元素的列表是波浪形的。

包含 2 个元素的列表是波浪形的,如果它在增加。

至少包含 3 个以 x1,x2,x3 开头的元素的列表是波浪形的,如果

  1. 我们在x1x2 之间“向上”,
  2. 我们在x2x3 之间“下降”,
  3. x3 开始的列表(包括x3)是波浪形的。

【讨论】:

  • 作为一种风格,你也可以写wave (x1 : x2 : xs@(x3 : _)) = x1 &lt; x2 &amp;&amp; x2 &gt; x3 &amp;&amp; wave xs,因为你只是匹配和重建x3 : xs
猜你喜欢
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多