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),那么它不会那么慢,因为懒惰会为您融合循环。如果你做了大量的串联,你将开始在内部循环中消耗时间。此外,您可能仍然有一个问题(特别是如果您以高度持久化的方式使用该列表),因为所有的垃圾消耗都会破坏您的缓存。