Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Haskell中编写反向函数_Haskell_Reverse - Fatal编程技术网

如何在Haskell中编写反向函数

如何在Haskell中编写反向函数,haskell,reverse,Haskell,Reverse,所以,我知道,Haskell中有一个内置函数来反转列表,但我正在尝试编写自己的小函数,只是为了练习一些Haskell。我想到了下面的代码,可惜它不起作用。你们能告诉我我做错了什么吗 rev :: [Int] -> [Int] rev [] = [] rev [x] = last [x] : rev init [x] 你差点就成功了 rev :: [Int] -> [Int] rev [] = [] rev x = last x : rev (init x)

所以,我知道,Haskell中有一个内置函数来反转列表,但我正在尝试编写自己的小函数,只是为了练习一些Haskell。我想到了下面的代码,可惜它不起作用。你们能告诉我我做错了什么吗

    rev :: [Int] -> [Int]
    rev [] = []
    rev [x] = last [x] : rev init [x]
你差点就成功了

rev :: [Int] -> [Int]
rev [] = []
rev x = last x : rev (init x)
说明:[x]是一个包含x的列表,而您希望直接使用x进行操作


还有,这是你的答案。请记住导入数据。列出

您可以这样做:

rev :: [Int] -> [Int]
rev [] = []
rev (x:l) = (rev l) ++ [x]

第三行从列表中获取第一个元素,然后创建一个仅包含该元素的列表。这将附加到递归调用的结果中。

如果您想有效地执行此操作,我建议您使用累加器:

rev :: [a] -> [a]
rev xs = go xs []
   where
   go :: [a] -> [a] -> [a]
   go []     ys = ys
   go (x:xs) ys = go xs (x:ys)
函数
go
在每一步从第一个列表
xs
中删除一个元素,并将其置于第二个列表
ys
的前面。这类似于从一个堆栈弹出并推到另一个堆栈——这会颠倒顺序

由于我们在每次递归调用中只使用恒定的时间量,因此我们得到了O(n)复杂度,其中n是列表长度


相反,如果在每次递归调用中使用
last
或追加
…++[x] 
,我们为每个呼叫支付O(n),因此总体上为O(n^2)。

[x]
是一个包含单个元素的列表(名为
x
last[x]
只是
x
,而
init[x]
[]
。所以
last[x]:revinit[x]
x:rev[]
,它是
x:[]
,它是
[x]
。因此,您的最后一行相当于
rev[x]=[x]
。但是你的主要问题是你没有一个包含多个元素的列表,这就是我要搜索的!谢谢!不客气!如果您觉得答案很好地回答了您的问题,请记住接受答案(单击绿色勾号)。我认为这甚至不能用
let
进行解析:感谢您发现错误
let
被删除。我认为这不是一个有效的
reverse
函数,因为许多调用了昂贵的
最后一个
函数。我认为这是一种更好的工作方式。