英文:
Haskell: I seem to not be able to link anything to my accumulator in following recursive function - can anyone explain where I am wrong here?
问题
我的解决方案:
start list = start' list []
where
start' (x:[]) acc = acc
start' (x:xs) acc = start' xs (acc ++ [x])
尝试编译时,GHC 似乎会因为第4行中的最后一个表达式 '(acc ++ [x])' 而抛出错误。有人能解释为什么吗?我不太关心这是否是解决问题的最有效方式 - 我只想知道我错在哪里。谢谢。
英文:
Task:
"Define a function 'start' that returns all the elements of a given list but the last one"
My solution:
start list = start' list []
where
start' (x:[]) acc = acc
start' (x:xs) acc = start' xs (acc:x)
When trying to compile, ghc seems to throw an error because of the very last expression in line 4 at '(acc:x)'.
Can somebody explain, why that is?
I don't really care if this is the most efficient way of solving this problem - I just want to get where I am wrong.
Thanks a lot.
答案1
得分: 3
(acc:x)
没有太多意义:acc
是一个列表,x
是一个元素。(:) :: a -> [a] -> [a]
接受一个项目和一个列表,并构造一个列表,其中项目是第一个项目,给定列表是结果中的剩余项目的列表。
你可以在右边附加元素:
start list = start' list []
where
start' (x : []) acc = acc
start' (x : xs) acc = start' xs (acc ++ [x])
你的 start
在这里基本上做了 init :: [a] -> [a]
做的事情,只是你的 start
版本还可以处理空列表。
然而,使用累加器是不必要的,只会增加计算工作和内存使用。你可以使用以下方式工作:
start :: [a] -> [a]
start [] = []
start (x : xs) = go xs x
where
go [] _ = []
go (x : xs) y = y : go xs x
或者更短:
start :: [a] -> [a]
start [] = []
start (x : xs) = go xs x
where
go [] = const []
go (x : xs) = (: go xs x)
这允许处理无限列表,其中 start
永远不会停止,但只需要有限的内存。
英文:
(acc:x)
makes not much sense: acc
is a list, x
is an element. (:) :: a -> [a] -> [a]
takes an item and a list, and construct a list where the item is the first item and the given list is the list of remaining items in the result.
You can append at the right end with:
<pre><code>start list = start' list []
where
start' (x : []) acc = acc
start' (x : xs) acc = start' xs (acc ++ [x])</code></pre>
Your start
here basically does what init :: [a] -> [a]
does, except that your start
version also works for empty lists.
Using an accumulator however is not necessary and will only increase the computational effort and memory usage. You can work with:
<pre><code>start :: [a] -> [a]
start [] = []
start (x : xs) = go xs x
where
go [] _ = []
go (x : xs) y = <b>y :</b> go xs x</code></pre>
or shorter:
<pre><code>start :: [a] -> [a]
start [] = []
start (x : xs) = go xs x
where
go [] = <b>const []</b>
go (x : xs) = <b>(:</b> go xs x<b>)</b></code></pre>
This allows to work with infinite lists as well, where the start
will never stop, but only needs a limited amount of memory.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论