【问题标题】:Taking the middle of a Haskell list; where am I going wrong?位于 Haskell 列表的中间;我哪里错了?
【发布时间】:2013-09-26 02:22:54
【问题描述】:

在我开始的函数式编程课程中,我正在尝试编写一个程序来返回给定列表的中间三分之一。据我所知,最直接的方法是获取列表的前三分之二,然后删除不需要的前三分之一,只返回中间三分之一。但是,我似乎无法正确使用语法。

middlethird :: [a] -> [a]
middlethird l
    |len `mod` 3 /= 0 = []
    |otherwise        = drop (1 `div`take ((2 `div` 3) len) l drop ((1 `div` 3)*len) l
    where len = length l

现在我在'where'上遇到一个解析错误,我不明白......但即使在此之前我只是为我输入的每个列表获取一个空集,而它应该只返回一个空当列表的长度不能被 3 整除时的列表。

我很困惑...任何帮助或指示将不胜感激。正如我所提到的,这是家庭作业的一部分,但这是最后一部分,其他一切似乎都运行良好。对不起,我的经验不足!

编辑:没关系,我想通了。

middlethird :: [a] -> [a]
middlethird l
    |mod len 3 /= 0 = []
    |otherwise =  drop (div len 3) (take (2*(div len 3)) l)
    where len = length l

【问题讨论】:

  • 这样想怎么样:设 n 为列表长度的三分之一。现在你想从列表中删除 n 并取出剩余的 n。

标签: haskell


【解决方案1】:

Haskell 使用带有大量空格的“布局”样式语法,很像 Python。在这种情况下,由于middlethirdwhere 的缩进相同,解析器认为where 应该是一个新的函数定义,因为您可以重新定义关键字,所以它会受到困扰。

此外,您的 otherwise 分支中有太多开放括号。

【讨论】:

    【解决方案2】:

    完全不清楚您认为您的代码应该如何工作。看起来您尝试将数字除以列表,并将数字作为函数调用,这两者都是 100% 非法的,而且您知道 - 您只是没有意识到代码中会发生这种情况。你能用更多的变量一步一步地写出你想要做的事情吗?可能是这样的:

    last_two_thirds_start_at = (2 * len) `div` 3
    list_of_first_two_thirds = take ... l
    ...
    list_with_middle_third = drop ... list_of_last_two_thirds
    

    真正明确地表达出来。测试解释器中的每一步,这样你就知道它做了你认为它做的事情。我绝对肯定,只要您停止恐慌并停止陷入括号的海洋,您就可以自己解决这个问题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-02
      相关资源
      最近更新 更多