1

In my beginning functional programming class, I'm trying to write a program to return the middle third of a given list. As far as I know, the most straightforward way to do this would be take the first two thirds of the list, then drop the unwanted first third, returning only the middle third. However, I just can't seem to get the syntax right.

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

Now I'm getting a parse error on 'where', which I don't understand... but even before that I was just getting an empty set for every list that I input, when it should only return an empty list when the length of the list isn't evenly divisible by 3.

I'm quite confused... any help or pointers would be greatly appreciated. As I mentioned, this is part of a homework assignment, but it's the very last part, and everything else seems to be running fine. Sorry for my inexperience!

EDIT: Nevermind, I figured it out.

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

2 回答 2

2

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

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

于 2013-09-26T02:35:50.027 回答
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

对此要非常明确。测试解释器中的每一步,这样你就知道它做了你认为它做的事情。我绝对肯定,如果您停止恐慌并不再让自己陷入括号的海洋,您就可以自己解决这个问题!

于 2013-09-26T02:37:26.953 回答