我想创建一个函数,从int的列表返回每个第三个int而不使用任何预定义的函数。 例如, everyThird [1,2,3,4,5] --> [1,4]
everyThird:: [a] -> [a]我可以继续使用tail迭代列表并每隔三次调用追加到一个新列表吗? 我是Haskell的新手并且对所有这些感到非常困惑
I want to create a function that returns every third int from a list of ints without using any predefined functions. For example, everyThird [1,2,3,4,5] --> [1,4]
everyThird:: [a] -> [a]Could I just continue to iterate over the list using tail and appending to a new list every third call? I am new to Haskell and very confused with all of this
最满意答案
你想要完全按照你所说的做法:遍历列表并仅在每次第三次调用时包含元素。 但是,有一个问题。 Haskell是一种有趣的语言,其中“改变”变量的想法没有意义,所以通常的方法是“有一个反向变量i告诉我们我们是否在第三个元素上”将不起作用通常的方式。 相反,我们将创建一个递归辅助函数来维护我们的计数。
everyThird :: [Int] -> [Int] everyThird xs = helper 0 xs where helper _ [] = [] helper 0 (x : xs) = x : helper 2 xs helper n (_ : xs) = helper (n - 1) xs我们在帮手中有三个案例。
如果列表为空,请停止并返回空列表。 如果计数器为0(即,如果我们在第三个元素上),则创建一个以当前元素开头并以其余计算结束的列表。 如果计数器不为零,则倒计时并继续迭代。由于模式匹配的工作方式,它将按顺序尝试这三个语句。
注意我们如何使用另一个参数作为计数器变量,因为我们不能像在命令式语言中那样改变变量。 另外,请注意我们如何递归地构造列表; 我们永远不会“追加”到现有列表,因为这意味着我们正在改变列表。 我们只是从头开始构建列表,并在第一轮结束时得到正确的结果。
You want to do exactly what you said: iterate over the list and include the element only on each third call. However, there's a problem. Haskell is a funny language where the idea of "changing" a variable doesn't make sense, so the usual approach of "have a counter variable i which tells us whether we're on the third element or not" won't work in the usual way. Instead, we'll create a recursive helper function to maintain the count for us.
everyThird :: [Int] -> [Int] everyThird xs = helper 0 xs where helper _ [] = [] helper 0 (x : xs) = x : helper 2 xs helper n (_ : xs) = helper (n - 1) xsWe have three cases in the helper.
If the list is empty, stop and return the empty list. If the counter is at 0 (that is, if we're on the third element), make a list starting with the current element and ending with the rest of the computation. If the counter is not at zero, count down and continue iteration.Because of the way pattern matching works, it will try these three statements in order.
Notice how we use an additional argument to be the counter variable since we can't mutate the variable like we would in an imperative language. Also, notice how we construct the list recursively; we never "append" to an existing list because that would imply that we're mutating the list. We simply build the list up from scratch and end up with the correct result on the first go round.
更多推荐
发布评论