Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.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,我是哈斯克尔的新手。 我写了一个简单的代码。 但它不起作用。 我得到了这个“不能构造无限类型”的错误。 它是如何修复的 reverse' list | null list = [] | otherwise = (reverse' (tail list)) : (head list) 问题源于您使用的:运算符,该运算符的类型为 (:) :: a -> [a] -> [a] 因此,它接受一个元素和一个列表,并返回一个新列表,其中该元素的前缀为。你在哪

我是哈斯克尔的新手。 我写了一个简单的代码。 但它不起作用。 我得到了这个“不能构造无限类型”的错误。 它是如何修复的

reverse' list
        | null list = []
        | otherwise = (reverse' (tail list)) : (head list) 

问题源于您使用的
运算符,该运算符的类型为

(:) :: a -> [a] -> [a]
因此,它接受一个元素和一个列表,并返回一个新列表,其中该元素的前缀为。你在哪里

reverse' (tail list) : head list
-- parentheses removed since they're not needed
反向(尾部列表)
的类型是
[a]
,而
头部列表的类型是
a
,因此编译器试图使其成为
a~[a]
,这显然无法工作。相反,您可以使用
++
运算符将
标题列表
放入列表本身:

reverse' (tail list) ++ [head list]

但请记住,这不是一个非常有效的解决方案,连接到Haskell列表末尾的速度很慢,因为它们是单链接列表。

问题是由于使用了
运算符,该运算符具有

(:) :: a -> [a] -> [a]
因此,它接受一个元素和一个列表,并返回一个新列表,其中该元素的前缀为。你在哪里

reverse' (tail list) : head list
-- parentheses removed since they're not needed
反向(尾部列表)
的类型是
[a]
,而
头部列表的类型是
a
,因此编译器试图使其成为
a~[a]
,这显然无法工作。相反,您可以使用
++
运算符将
标题列表
放入列表本身:

reverse' (tail list) ++ [head list]

但是请记住,这不是一个非常有效的解决方案,连接到Haskell列表末尾的速度很慢,因为它们是单独链接的列表。

@antoniomasa学习函数或类型最有用的技巧之一是GHCi中的
:info
(缩写
:i
)命令。尝试使用诸如
:i(:)
:i Int
:i Num
,以及更多内容来探索这个交互式工具。当试图弄清楚如何使用函数或数据类型时,它会有很大帮助。由于懒惰,连接到末尾的速度并没有那么慢。@Nicolas我决定用基本相同的算法使用criteria()对其进行基准测试。数字本身就说明了问题,使用列表,10000个元素的列表平均需要1.15秒,stddev为92.5毫秒。使用同一列表上的
Data.Seq
(刚刚转换为序列),平均值为1.0ms,标准差差值为123.1us。使用
Data.Seq
,速度大约提高了1000倍。为了好玩,我添加了一些其他的基准测试,你可以在要点中看到,最快的是
Prelude.reverse
。懒惰救不了你here@Nicolas,如果您只有一个或几个连接(并且您实际上是在遍历列表,而不仅仅是为了好玩而遍历一个deepSeq),那么它不会那么慢,因为懒惰会为您融合循环。如果你做了大量的串联,你将开始在内部循环中消耗时间。此外,您可能仍然有问题(特别是如果您以高度持久化的方式使用列表),因为所有垃圾消耗都会破坏缓存。@antoniomasa了解函数或类型最有用的技巧之一是GHCi中的
:info
(缩写
:i
)命令。尝试使用诸如
:i(:)
:i Int
:i Num
,以及更多内容来探索这个交互式工具。当试图弄清楚如何使用函数或数据类型时,它会有很大帮助。由于懒惰,连接到末尾的速度并没有那么慢。@Nicolas我决定用基本相同的算法使用criteria()对其进行基准测试。数字本身就说明了问题,使用列表,10000个元素的列表平均需要1.15秒,stddev为92.5毫秒。使用同一列表上的
Data.Seq
(刚刚转换为序列),平均值为1.0ms,标准差差值为123.1us。使用
Data.Seq
,速度大约提高了1000倍。为了好玩,我添加了一些其他的基准测试,你可以在要点中看到,最快的是
Prelude.reverse
。懒惰救不了你here@Nicolas,如果您只有一个或几个连接(并且您实际上是在遍历列表,而不仅仅是为了好玩而遍历一个deepSeq),那么它不会那么慢,因为懒惰会为您融合循环。如果你做了大量的串联,你将开始在内部循环中消耗时间。此外,您可能仍然有一个问题(特别是如果您以高度持久化的方式使用该列表),因为所有的垃圾消耗都会破坏您的缓存。