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 - Fatal编程技术网

Haskell 递归地反转字符串(或列表)

Haskell 递归地反转字符串(或列表),haskell,Haskell,我正在尝试用haskell编写一个递归反转列表的函数。我编写了一个helper函数,它接受原始列表和一个空列表,然后以后进先出模式将元素从第一个列表传输到另一个列表 以下是我所拥有的: myreverse :: [a] -> [a] myreverse list = myflip list [] myflip :: [a] -> [a] -> [a] myflip list1 newList | null list1 = newList | ot

我正在尝试用haskell编写一个递归反转列表的函数。我编写了一个helper函数,它接受原始列表和一个空列表,然后以后进先出模式将元素从第一个列表传输到另一个列表

以下是我所拥有的:

myreverse :: [a] -> [a]
myreverse list = myflip list []

myflip :: [a] -> [a] -> [a]
myflip list1 newList
    | null list1        = newList
    | otherwise         = myflip (tail list1) ((head list1) : newList)
我知道有一个内置函数可以为我实现这一点,但要求我只使用head、tail、elem和null(也没有模式匹配)。所以我的问题是:有没有更好的解决方案,我只有一个函数myreverse,它只使用一个列表?(当然,满足上述要求)


谢谢

您可以尝试使用
foldl
反转列表,如下所示:

reverse' :: [a] -> [a]  
reverse' = foldl (\acc x -> x : acc) [] 

此功能满足您的要求,但效率低下:

rev xs = if null xs then xs else rev (tail xs) ++ [head xs]

你的解决方案一点也不坏。在使用模式匹配并使
myFlip
成为本地函数之后,它看起来就不会难看了。使用本地函数和累加器的技术非常常见(尽管在这种情况下并不容易)。

除了满足附加要求所需的调整之外,您的函数与
反转的方式相当。因此,我认为您的函数是非常好的。

因此,对于任何可能感兴趣的人,我最后写的是:

myreverse :: [a] -> [a]
myreverse list = myflip list []
    where myflip list newList = if null list then newList
                                else myflip (tail list) ((head list):newList)

谢谢大家的评论和建议。

将此保存在reverse.hs文件中

 reverseString :: [Char] -> [Char]
 reverseString [] = []
 reverseString (x:xs) = reverseString xs ++ [x]
然后跑 反向限制“abc”

cba


是的。我的成绩会得到满分。考虑到上述要求,我只想知道是否有更优雅的方法来实现它。您也在使用
(:)
,但它不在允许的函数列表中;-)是的,有很多方法可以做到这一点,但由于受到限制,很难设计出一个好的函数。:)它是不可解的,因为tail、elem、head和null都不会产生一个类型相同的列表,并且至少和其中一个参数一样长。但结果必须是一个与参数类型和长度相同的列表。Q.E.D.@sth
(:)
是数据构造函数,而不是类型构造函数。它的类型是
(:)::a->[a]->[a]
,因此它在逻辑上是一个函数,因为它的类型至少包含一个箭头。上的wikipedia页面将数据构造函数描述为有点类似于函数,但在下一句中,它在逻辑上是一个函数。当然,如果我们想有任何解决问题的希望,我们必须允许它的使用!或者稍微喜欢的
foldl(flip(:)[
谢谢,但这不符合要求:@Sadiq
reverse'sNew=foldl(flip(:))sNew
获取2个列表并返回反向字符串。请记住,Haskell总是返回一个新值。我不知道为什么你需要传递一个值来保存你的新结果。不可变语言不会像命令式语言那样遭受同样的危险。我考虑过这一点,但不幸的是,++运算符不符合要求:(谢谢你的帮助!@Uqi:然后写你自己的
++
应用程序xs ys=如果为空xs,那么ys-else头xs:app(尾xs)ys